简体   繁体   中英

allow unique key column to use null value as key instead of ignoring it

I am new to using graph ql, and I am trying to set up a unique key for one of my tables.

For context, the table's key will be determined on the combination of part_number + organization_id. So each organization ID can only have one part_number, but different organizations can have the same part_number.

The issue I am running into is that organization_id is a nullable field. When null, this represents global data. So essentially, I want it to act the same as an organization_id.

IE, if I had the part_number: ABC123, I want to enforce that only one of those exist for each organization_id AND only one of those exists for a row with no organization_id.

Currently, I have a unique key set to product_pn_organization_id, and everything works fine for products with an organization ID, but as soon as the organization ID is null graph ql completely ignores the unique key constraint. So when I run an insert mutation with the product_pn_organization_id constraint on a part_number: ABC123 organization_id: null (assuming this already exists) instead of updating the row, it creates a new row.

If I run the same insert with an organization_id (part_number: ABC123, organization_id: 1, again assuming this row already exists) it will update the columns instead of creating a new row.

Right now, the only solution I can think of is creating an organization that represents 'global' and having that as the default organization_id so that organization_id is never actually null. However, I would rather avoid that if possible.

Hoping someone has some advice on how to move forward here. Thanks!

Per request, here are the mutations:

This mutation inserts a new row with organization_id set to null.

mutation MyMutation {
  insert_products(objects: {pn: "ABC123", manufacturer_pn: "MANABC123"}, on_conflict: {constraint: products_pn_organization_id_key, update_columns: manufacturer_pn}) {
    returning {
      id
    }
  }
}

Ideally, this query would update the row from the first query, but instead creates a new row.

mutation MyMutation {
  insert_products(objects: {pn: "ABC123", manufacturer_pn: "MANABC124"}, on_conflict: {constraint: products_pn_organization_id_key, update_columns: manufacturer_pn}) {
    returning {
      id
    }
  }
}

This query inserts the same PN but with an organization_id.

mutation MyMutation {
  insert_products(objects: {pn: "ABC123", manufacturer_pn: "MANABC123", organization_id: "00000000-0000-0000-0000-000000000000"}, on_conflict: {constraint: products_pn_organization_id_key, update_columns: manufacturer_pn}) {
    returning {
      id
    }
  }
}

Unlike the second query, this query actually updates the row belonging to the organization_id/pn combination instead of creating a new row.

mutation MyMutation {
  insert_products(objects: {pn: "ABC123", manufacturer_pn: "MANABC124", organization_id: "00000000-0000-0000-0000-000000000000"}, on_conflict: {constraint: products_pn_organization_id_key, update_columns: manufacturer_pn}) {
    returning {
      id
    }
  }
}

You are probably running on top of a Postgres DB, and you need to update to V 15 to get support for this. More info here , and an excerpt:

In Postgres 14 and older versions unique constraints always treat NULL values as not equal to other NULL values. If you're inserting a NULL value into a table and you have a unique constraint, the NULL value is considered to be distinct on its own. NULL is always different from another NULL. When you're inserting five records into the "old_null_style" table where "val1" is just always the same value "Hello" and then "val2" is always NULL.

Even though you have a unique constraint that actually supports you inserting that five times or as many times as you'd like, because you have that NULL value that makes each row distinct from another and because the unique constraint includes both "val1" and "val2", all the rows are unique.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM