microsoft / mssql-django

The Microsoft Django backend for SQL Server provides a connectivity layer for Django on SQL Server or Azure SQL DB.
Other
351 stars 115 forks source link

UniqueConstraint on three fields doesn't throw ValidationError #419

Open iamjameswalters opened 2 weeks ago

iamjameswalters commented 2 weeks ago

I have a model with a UniqueConstraint across 3 different fields, and while the constraint works correctly at the database level, I expect this to bubble up as a ValidationError, and return the violation_error_message back to the form, but instead I get a stacktrace/500.

Software versions

Model

class Client(models.Model):
  # Put whatever you like here, it's just an FK below

class Location(models.Model):
  # Put whatever you like here, it's just an FK below

class Alert(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    location = models.ForeignKey(
        Location, on_delete=models.CASCADE, blank=True, null=True
    )
    title = models.CharField(max_length=100)
    expire_date = models.DateTimeField()
    details = models.TextField(blank=True, null=True)

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["client", "location", "title"],
                name="Unique_Alert_Per_Location_Per_Client",
                violation_error_message="An alert with this title already exists for this location.",
            ),
        ]

Problem description and steps to reproduce

  1. Create a client (particulars of this model don't matter, it's a ForeignKey field on Alert model)
  2. Create an alert for this client with title of Test.
  3. Try to create another alert for this client with title of Test.

Expected behavior and actual behavior

Error message/stack trace

('23000', "[23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Violation of UNIQUE KEY constraint 'Unique_Alert_Per_Location_Per_Client'. Cannot insert duplicate key in object 'dbo.clients_alert'. The duplicate key value is (4, <NULL>, Test). (2627) (SQLExecDirectW); [23000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The statement has been terminated. (3621)")