mssql-django 中的限制和未受支持的功能

本文列出了在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-django JSONField映射到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__iregex and 查找功能在 Azure SQL 数据库 上不可用。
  • 连接用户必须拥有 sysadmin 或 ALTER SETTINGS 许可。 管理命令会自动启用CLR。
  • mssql应用必须在 INSTALLED_APPS。

安装CLR组件

运行管理命令,传递你的数据库名称:

python manage.py install_regex_clr <database>

该命令执行以下步骤:

  1. 如果服务器上还没启用,则启用 (sp_configure 'clr enabled', 1) 的 CLR。
  2. 设置为clr strict security0 (SQL Server 2017及更高版本的汇编必须SAFE使用)。
  3. 从捆绑的DLL创建 regex_clr 汇编。
  4. 创建 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 命令。 如果数据库被丢弃并重新创建(例如测试时),请再次执行该命令。