beam icon indicating copy to clipboard operation
beam copied to clipboard

How to manually annotate FOREIGN KEY constraint for composite keys?

Open thomasjm opened this issue 3 years ago • 0 comments

This is a follow-up question from the discussion on #502. I'm interested in manually annotating my migrations with FOREIGN KEY constraints, and couldn't figure out howh to do it in the case of multi-field keys.

I've been successfully writing things like ON DELETE CASCADE constraints by defining them manually like this:

referencesUsersTableDeleteCascade :: BeamMigrateSqlBackend be => BM.Constraint be
referencesUsersTableDeleteCascade = Constraint $ referencesConstraintSyntax "users" ["username"] Nothing Nothing (Just referentialActionCascadeSyntax)

And then when describing the migration for some other table,

  ...
  , _userSettingsUsername = UserId $ field "username" (varchar Nothing) notNull unique referencesUsersTableDeleteCascade
  ...

However, what if you have a table like this?

instance Table FooT where
  data PrimaryKey FooT f = FooId { namespace :: (Columnar f Text), name :: (Columnar f Text) } deriving (Generic, Beamable)

Normally I write the migration like this:

...
  , _foreignFoo = FooId (field "foo_namespace" (varchar Nothing) notNull)
                        (field "foo_name" (varchar Nothing) notNull)
...

Now, I can stick a Constraint in the individual field parts above, which yields REFERENCES ... ON DELETE CASCADE on the individual fields. But that doesn't work on SQLite to reference a composite key; instead I need a separate constraint to be emitted in the CREATE TABLE command; see here.

Is there some way to accomplish this in Beam?

thomasjm avatar Oct 23 '22 11:10 thomasjm