本文列出了在SQL Server、Azure SQL 数据库、Azure SQL 托管实例和Microsoft Fabric中的SQL数据库中使用后端时的mssql-django限制。
Django 功能的限制
以下Django功能不支持或支持有限 mssql-django :
| 功能 / 特点 | 地位 | 详细信息 |
|---|---|---|
Avg 与 DurationField |
不支持 | 聚合 Avg 在 上不起作用 DurationField。 |
__regex 以及 __iregex 查找 |
需要设置 | 在SQL Server或Azure SQL 托管实例安装CLR汇编后才得到支持。 Azure SQL 数据库不支持 CLR assemblys。 参见 设置正则表达式查询。 |
DISTINCT ON |
不支持 | SQL Server不支持DISTINCT ON从句。 使用 .values().distinct() 或子查询。 |
Subquery 在 ORDER BY 中 |
不支持 | 按子查询表达式排序可能不起作用。 |
数据库层面 CASCADE |
有限 | 有些 SET NULL 操作 SET DEFAULT 可能需要手动迁移SQL。 |
DB_CASCADE、DB_SET_NULL、DB_SET_DEFAULT |
不支持 | Django 6.1 中新增的数据库级引用操作。 SQL Server 拒绝带有多条级联路径的外键图(错误 1785),因此在任何 SQL Server 版本中都没有该功能的原生路径。 使用其中一个值会提高Django系统检查 fields.E324。 改用标准的Django级别 on_delete 。 |
BitAnd、BitOr、BitXor |
不支持 | Django 6.1 中添加了按位汇总。 SQL Server没有原生的按位聚合函数,后端也不模拟,因此这些聚合会生成 NotSupportedError。 |
is_dst 在 Trunc/Extract |
不支持 |
is_dst参数(用于解决夏令时过渡期间的模糊时间)在中Extract()Trunc()且不被支持。 在原始SQL中用于 AT TIME ZONE 支持DST的查询。 |
| 浮点注释 | 有限 | 由于 SQL Server 的Avg类型行为,浮点聚合可能会比 PostgreSQL 更差。 例如,平均值0.1和0.2可能得到0.15000000000000000222,而不是恰好0.15。 用于DecimalFieldCast(avg_expr, output_field=DecimalField())或用于关键的财务计算。 |
注释/存在于 ORDER BY |
不支持 | 用注释或存在表达式可能 order_by 不行。 |
| 右手幂与日期时间算术 | 不支持 | 右手幂运算(例如, F('value') ** 2 能用但 2 ** F('value') 失败)和除 timedelta 法不被支持。 |
| 时区与时差 | 有限 | 时区和时差并不完全支持。 参见 mssql-django 中的时区支持。 |
QuerySet.iterator() 没有火星 |
有限 | mssql-python路径不启用多重主动结果集(MARS)。 在 pyodbc 路径上,MARS 默认启用,使用 Windows 的 Microsoft ODBC 驱动,并且MARS_Connectionextra_params不区分大小写。 当MARS关闭时,会 QuerySet.iterator() 在释放前将整个结果缓冲在内存中。
chunk_size 但这并不能改变这种行为。 |
NthValue 窗口函数 |
不支持 | SQL Server不支持 NTH_VALUE()。 使用 FIRST_VALUE、 LAST_VALUE或子查询。 |
ignore_conflicts 在 bulk_create 中 |
不支持 | 不支持 bulk_create(objs, ignore_conflicts=True)。 SQL Server 没有 PostgreSQL ON CONFLICT DO NOTHING的对应工具。 |
JSONField contains lookup |
不支持 | 改用密钥路径查找(例如, filter(metadata__color="blue"))。 参见 JSONField 限制。 |
select_for_update(of=(...)) |
不支持 | SQL Server不支持锁定特定表。 后端会加 NotSupportedError注。 参见 事务管理。 |
迁移限制
| 限度 | 详细信息 |
|---|---|
祭坛 AutoField |
无法将字段改为(列)或从(AutoFieldIDENTITY列)切换。 需要创建一个新的表。 |
| 用外键重命名 | 重命名带有外键约束的列可能会失败。 使用 SeparateDatabaseAndState。 |
AddConstraint
/
RemoveConstraint 冲突 |
某些约束操作可能会冲突。 分开申请。 |
| 日期提取操作 |
ExtractYear, ExtractMonth以及类似操作的支持有限 tzinfo 。 |
JSONField 限制
-
mssql-djangoJSONField映射到Nvarchar(Max)。 SQL Server 2025引入了原生json类型,但Microsoft的SQL Server驱动没有暴露该类型。 -
contains查询功能不被支持。 改用密钥路径查找(例如,filter(metadata__color="blue"))。 - 带引号的字符串值会返回带有额外的引号(例如,
'"value"'代替'value')。 - 有些嵌套查找的表现可能和PostgreSQL不同。
- 更多信息请参见 SQL Server 中的 JSONField。
InspectDB 局限性
- 复合主键不会像现在那样
unique_together自动生成。 - 某些 SQL Server 特定的列类型可能会映射到通用的 Django 字段。
- 手动审查并调整生成的模型。
- 更多信息请参见 使用 inspectdb 的逆向工程模型。
SQL Server 参数限制
SQL Server 限制每个查询最多 2,100 个参数。 这一限制影响了生成具有大量值列表的参数化查询的Django操作:
| 运算 | 如何达到极限 |
|---|---|
filter(field__in=large_list) |
每个列表项目都变成了一个参数。 后端会自动将2048多个项目列表整理到临时表中。 |
prefetch_related() |
每个父对象 ID 都成为相关查询 WHERE IN 子句中的一个参数。 自动优化,比如 filter(field__in=...) 超过2048个ID。 |
bulk_create() |
每个物体的每个场都成为一个参数。 一个包含10个字段和250个对象的模型生成2500个参数。 |
bulk_update() |
每个字段为每个对象使用两个参数(一个用于PK匹配,一个用于值)。 |
Q() 有许多条件 |
链状 Q 对象中的每个值都成为一个参数。 |
设置为 batch_size 批量操作和大 IN 块查询。 有关解决方案,请参见 性能调优 。
散装作业的限制
-
bulk_create与 不return_rows_bulk_insert=False返回 ID。 对于带有触发器的表格,这是必需的。 参见 mssql-django 的批量操作。
测试框架的局限性
--keepdb 在使用托管身份认证ActiveDirectoryMsi()时是必需的,因为测试运行者无法使用该认证方法创建或销毁数据库。
更多信息请参见使用 SQL Server 测试 Django 应用。
版本专属注释
| MSSQL-Django 版本 | 备注 |
|---|---|
| 2.0 | 支持 Python 3.10 至 3.14、Django 5.2、6.0 和 6.1,SQL Server 2017、2019、2022 和 2025,Azure SQL 数据库、Azure SQL 托管实例 以及 Microsoft Fabric 中的 SQL 数据库。 在默认使用pyodbc的同时,增加了mssql-python驱动路径。 欲了解更多信息,请参见 MSSQL-django 的选择数据库驱动程序。 |
| 1.8.0 | 该版本用于需要 Python 3.8、Python 3.9 或 5.2 之前的 Django 版本的项目。 |
测试过的mssql-django 2.0组合是Django 5.2搭配Python 3.10到3.13,以及Django 6.0或6.1搭配Python 3.12到3.14。 如果后端连接到未识别的较新 SQL Server 主要版本,它会使用已知的最新能力集,而不是失败的版本验证。 这种行为并不意味着支持未经测试的功能。
Django 版本专属注释
| Django 版本 | 备注 |
|---|---|
| 5.2 |
CompositePrimaryKey 支持是部分的。
inspectdb 仍然需要手动修复,元组与子查询的比较需要Django 5.2.4及更高版本,还有一些迁移以及JSONField的批量/CASE WHEN,更新路径仍然存在测试排除。 更多信息请参见 GitHub 仓库。 |
| 6.0 | 需要 Python 3.12 及更高版本。 所有5.2的限制都适用。 后端透明地处理所有6.0 API的变更。 |
| 6.1 | 需要 Python 3.12 及更高版本。 所有6.0的限制都适用。 需要 mssql-django 1.8.0及更高版本。 不支持数据库级的引用操作(DB_CASCADE, DB_SET_NULL, DB_SET_DEFAULT)和位汇总(BitAnd, BitOrBitXor, )。 |
设置正则表达式查找
mssql-django后端支持 Django __regex 和__iregex查找,但需要一次性设置步骤。 后端会附带一个CLR汇编(regex_clr.dll),为SQL Server提供dbo.REGEXP_LIKE一个函数。
先决条件
- 一个支持CLR集成的SQL Server实例。 本地 SQL Server 和 Azure SQL 托管实例 支持 CLR。
Azure SQL 数据库不支持 CLR assemblys,所以
__regex__iregexand 查找功能在 Azure SQL 数据库 上不可用。 - 连接用户必须拥有
sysadmin或ALTER SETTINGS许可。 管理命令会自动启用CLR。 -
mssql应用必须在INSTALLED_APPS。
安装CLR组件
运行管理命令,传递你的数据库名称:
python manage.py install_regex_clr <database>
该命令执行以下步骤:
- 如果服务器上还没启用,则启用 (
sp_configure 'clr enabled', 1) 的 CLR。 - 设置为
clr strict security0(SQL Server 2017及更高版本的汇编必须SAFE使用)。 - 从捆绑的DLL创建
regex_clr汇编。 - 创建
dbo.REGEXP_LIKE标量函数。
注意
设置为 clr strict security0 允许未签名的 CLR 组件加载。 这是必须的,因为捆 regex_clr.dll 绑包没有签名。 在生产服务器上运行命令前,先和你的DBA讨论这个变更。 该设置适用于服务器范围,而非单个数据库。
使用正则表达式查找
安装汇编后,使用 __regex 和 __iregex 在查询集中:
# Case-sensitive regex
products = Product.objects.filter(name__regex=r"^Widget\s\d+$")
# Case-insensitive regex
products = Product.objects.filter(name__iregex=r"^widget\s\d+$")
后端将这些查找 dbo.REGEXP_LIKE(column, pattern, case_flag) = 1转换为 。
Important
dbo.REGEXP_LIKE 忽略图案中的字面空白。 像 这样的模式 匹配 ^Widget \d+$ ,就像 一样 ^Widget\d+$,因此它不会返回任何对值 Widget 42的行。 将空格写成 \s 或写成如 的字符类 [ ]。 没有任何数据被抬高,所以空的结果看起来像是数据问题。
Note
你必须在每个数据库中执行一次该 install_regex_clr 命令。 如果数据库被丢弃并重新创建(例如测试时),请再次执行该命令。