gpt4 book ai didi

python - 我应该总是使用 'implicit_returning' :False in SQLAlchemy?

转载 作者:太空宇宙 更新时间:2023-11-03 12:04:35 24 4
gpt4 key购买 nike

在 SQLAlchemy 中始终使用 'implicit_returning': False 的潜在陷阱是什么?

在处理定义了触发器的 MSSQL 表时,我遇到过很多次问题,并且由于数据库处于复制状态,所以所有表都有触发器。

我现在不确定到底是什么问题。它与自动递增字段有关 - 可能是因为我正在预取自动递增的值,所以我可以将它插入另一个表中。

如果我没有为表设置 'implicit_returning': False,当我尝试插入值时,我会收到此错误:

The target table of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.

那么,如果为了安全起见,我将 __table_args__ = {'implicit_returning': False} 放入所有映射类中呢?

特别令我沮丧的是,我用于开发和测试的本地数据库不在复制中,不需要该选项,但生产数据库被复制,所以当我部署更改时,它们有时不起作用。 :)

最佳答案

您可能已经知道,SQLAlchemy Docs 中描述了您陷入困境的原因。如下所示:

SQLAlchemy by default uses OUTPUT INSERTED to get at newly generated primary key values via IDENTITY columns or other server side defaults. MS-SQL does not allow the usage of OUTPUT INSERTED on tables that have triggers. To disable the usage of OUTPUT INSERTED on a per-table basis, specify implicit_returning=False for each Table which has triggers.

如果您将 SQLAlchemy 引擎设置为回显 SQL,您将看到默认情况下它会执行以下操作:

INSERT INTO [table] (id, ...) OUTPUT inserted.[id] VALUES (...)

但是如果您禁用 implicit_returning,它会改为这样做:

INSERT INTO [table] (id, ...) VALUES (...); select scope_identity()

所以问题是,“为了以防万一,禁用所有表的 implicit_returning 有什么坏处吗?”实际上,“使用 SCOPE_IDENTITY() 而不是 OUTPUT INSERTED 有什么缺点吗?”

我不是专家,但我的印象是,虽然 OUTPUT INSERTED 是目前首选的方法,但 SCOPE_IDENTITY() 通常也不错。过去,SQL Server 2008(也许还有更早的版本?)有一个错误,SCOPE_IDENTITY 有时不会返回正确的值,但我听说现在已修复 (see this question for more detail)。 (另一方面,@@IDENTITYIDENT_CURRENT() 等其他技术仍然很危险,因为它们可能在极端情况下返回错误的值。参见 this answer 和同一页面上的其他人了解更多详情。)

OUTPUT INSERTED 仍然具有的一大优势是它可以用于通过单个 INSERT 语句插入多行的情况。那是你用 SQLAlchemy 做的事情吗?可能不是,对吧?所以没关系。

请注意,如果您将不得不为许多表禁用 implicit_returning,您可以通过为它制作一个 mixin 来避免一些样板(以及您想要的所有其他列和属性)要继承的表):

class AutoincTriggerMixin():
__table_args__ = {
'implicit_returning': False
}

id = Column(Integer, primary_key=True, autoincrement=True)

class SomeModel(AutoincTriggerMixin, Base):
some_column = Column(String(1000))
...

参见 this page in the SQLALchemy documentation了解更多详情。作为一个额外的好处,它使哪些表涉及触发器变得更加明显。

关于python - 我应该总是使用 'implicit_returning' :False in SQLAlchemy?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36109206/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com