Request for comments about a ticket: Index vs UniqueConstraint inconsistency

I accepted this ticket: #34949 (Fails to create unique constraints) – Django describing the behaviour inconsistency between Index and UniqueConstraint and wanted to elicit some discussion here.

tl;dr Index with include only ignores the option if not supported whereas UniqueConstraint with either include or nulls_distinct ignores the whole constraint if not supported.

Should this be a doc update or do we want to bring the behaviour inline?

Some thoughts:

  • UniqueConstraint has long-standing history of not creating the constraint if supplied option is not supported (eg deferrable). Changing behaviour to make only include or nulls_distinct options be ignore yet creating the constraint would make it internally inconsistent.
  • Is changing Index to behave like UniqueConstraint a better option?
  • Currently docs state with admonition “Deferrable unique constraints are ignored on MySQL, MariaDB, and SQLite as neither supports them.” yet no such admonition for include. If we go with doc update then I’d suggest doing that.

I think the two options need different treatment.

include is only an optimization, as the ticket’s OP noted. I don’t think a constraint should be skipped because it uses include when not supported.

On the other hand, nulls_distinct affects the constraint’s behaviour. Skipping creation there makes sense when not supported, in line with the current deferrable behaviour.

1 Like

Cheers your arguments make sense :+1:

Hm since you’re the only one responded and that I think I agree with you I’ll comment that we’ve reached consensus :sweat_smile:

But then we have a different question. How do we instruct Django to create Index(fields=[“a”], include=[“b”]) if supported but Index(fields=[“a”, “b”]) if not supported?

I don’t agree, users will get a clear message when using unsupported option in this case models.W039:

“models.W039: does not support unique constraints with non-key columns.”
“A constraint won’t be created. Silence this warning if you don’t care about it.”

It they want such constraint to be created by Django it’s enough for them to remove include from it’s declaration. I don’t think it’s better to pretend something is supported when it is not.

Ah, I was not aware of this warning. Yeah, it makes sense to skip the whole constraint using include in that case, then.