-
Notifications
You must be signed in to change notification settings - Fork 130
Description
Microsoft SQL server has a set of maximum capacity specifications as documented Maximum capacity specifications for SQL Server
The DatabaseWrapper.data_types dictionary contains a max parameter for some fields in the database that may or may not have a max_length size set in the applications model:
Lines 74 to 102 in ff59848
| data_types = { | |
| 'AutoField': 'int', | |
| 'BigAutoField': 'bigint', | |
| 'BigIntegerField': 'bigint', | |
| 'BinaryField': 'varbinary(max)', | |
| 'BooleanField': 'bit', | |
| 'CharField': 'nvarchar(%(max_length)s)', | |
| 'DateField': 'date', | |
| 'DateTimeField': 'datetime2', | |
| 'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)', | |
| 'DurationField': 'bigint', | |
| 'FileField': 'nvarchar(%(max_length)s)', | |
| 'FilePathField': 'nvarchar(%(max_length)s)', | |
| 'FloatField': 'double precision', | |
| 'IntegerField': 'int', | |
| 'IPAddressField': 'nvarchar(15)', | |
| 'GenericIPAddressField': 'nvarchar(39)', | |
| 'JSONField': 'nvarchar(max)', | |
| 'NullBooleanField': 'bit', | |
| 'OneToOneField': 'int', | |
| 'PositiveIntegerField': 'int', | |
| 'PositiveSmallIntegerField': 'smallint', | |
| 'SlugField': 'nvarchar(%(max_length)s)', | |
| 'SmallAutoField': 'smallint', | |
| 'SmallIntegerField': 'smallint', | |
| 'TextField': 'nvarchar(max)', | |
| 'TimeField': 'time', | |
| 'UUIDField': 'char(32)', | |
| } |
Specifically, BinaryField, JSONField, TextField have a corresponding max size set instead of respecting the max_length property that can be set in an application's model.
For example:
class ClientDownload(models.Model):
access_code = models.BinaryField(max_length=15, default=random_access_code, unique=True)
# ...A developer should expect the access_code field to be created in the database with the type varbinary(15) (or binary(15), but that may be out of scope of this issue). However, since the field's type will end up with varbinary(max), the unique=True constraint will throw an exception from SQL server as the field is too large to be indexed.
[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Column 'access_code' in table 'mypp_clientupload' is of a type that is invalid for use as a key column in an index. (1919) (SQLExecDirectW); [42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Could not create constraint or index. See previous errors. (1750)
This is due to the maximum bytes allowed for an indexable field
| SQL Server Database Engine object | Maximum sizes/numbers SQL Server (64-bit) | Additional Information |
|---|---|---|
| Bytes per index key | 900 bytes for a clustered index. 1,700 for a nonclustered index. | The maximum number of bytes in a clustered index key cannot exceed 900 in SQL Server. For a nonclustered index key, the maximum is 1700 bytes. You can define a key using variable-length columns whose maximum sizes add up to more than the limit. However, the combined sizes of the data in those columns can never exceed the limit. In a nonclustered index, you can include extra non-key columns, and they do not count against the size limit of the key. The non-key columns might help some queries perform better. |