graphback icon indicating copy to clipboard operation
graphback copied to clipboard

[Migrations] Ability to specify "CHECK" constraints and Auto-add them "CHECK" for enum types

Open machi1990 opened this issue 4 years ago • 7 comments

machi1990 avatar Aug 10 '20 11:08 machi1990

/cc @craicoverflow, @wtrocki Automatically generated comment to notify maintainers

machi1990 avatar Aug 10 '20 11:08 machi1990

Is it possible to add a check constraint to enum database types? I know very little about them, but I could not find anything about adding a CHECK constraint to a database enum.

craicoverflow avatar Aug 11 '20 08:08 craicoverflow

The idea will be to check that the string is within the given enumeration values CHECK IN (....).

machi1990 avatar Aug 11 '20 08:08 machi1990

Ah, in that case this seems sensible. Would it be better to map enums to database enums instead?

craicoverflow avatar Aug 11 '20 08:08 craicoverflow

Not sure if that will work across different relational database, SQLite, MySQL etc. But worth a separate discussion.

machi1990 avatar Aug 11 '20 08:08 machi1990

cc @machi1990 can you add more info, maybe with the new issue template?

craicoverflow avatar Aug 20 '20 10:08 craicoverflow

SQL has check constraints e.g https://www.postgresql.org/docs/9.4/ddl-constraints.html which automatically verifies the valid of data under the given constraints.

With this feature we'll be looking to support defining them via an annotation, let me call it @db(check: []).

Taking the products table from the shared link above, this could then be modeled as:

@model
@db(name: 'products')
type Product {
    """
    @id
    """
    product_no: ID!
    name: String,

    """
    @db(check: ['price > 0'])
    """
    price: ID  
}

The constraint can be named too, and in this case:

@model
@db(name: 'products')
type Product {
    """
    @id
    """
    product_no: ID!
    name: String,

    """
    @db(check: [{name: 'positive_price', constraint: 'price > 0' }])
    """
    price: ID  
}

can be applied to several fields, where a declaration can refer to another field.

@model
@db(name: 'products')
type Product {
    """
    @id
    """
    product_no: ID!
    name: String,

    """
    @db(check: [{name: 'positive_price', constraint: 'price > 0' }])
    """
    price: ID  

   """
   @db(check: ['discounted_price > 0', 'price > discounted_price'])
   """
   discounted_price: ID
}

The "check in" constraint can be applied to enum type for database that do not support them e.g SQLite.

Does something like that make sense and we'll want to support?

machi1990 avatar Aug 24 '20 09:08 machi1990