我有一个Test
模型/表和一个TestAuditLog
模型/表,使用SQLAlchemy和SQL Server 2008。两者之间的关系是Test.id == TestAuditLog.entityId
,一个测试有许多审计日志。TestAuditLog
旨在保留Test
表中行的更改历史。我想跟踪Test
何时被删除,但我对此有困难。在sqlservermanagementstudio中,我将FK_TEST_AUDIT_LOG_TEST
关系的“Enforce Foreign Key Constraint”属性设置为“否”,认为这将允许TestAuditLog
行与不再连接到任何Test.id
的entityId
一起存在,因为Test
已被删除。但是,当我试图用SQLAlchemy创建一个TestAuditLog
,然后删除Test
时,会得到一个错误:
(IntegrityError) ('23000', "[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]Cannot insert the value NULL into column 'AL_TEST_ID', table 'TEST_AUDIT_LOG'; column does not allow nulls. UPDATE fails. (515) (SQLExecDirectW); [01000] [Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. (3621)") u'UPDATE [TEST_AUDIT_LOG] SET [AL_TEST_ID]=? WHERE [TEST_AUDIT_LOG].[AL_ID] = ?' (None, 8)
我认为由于Test
和TestAuditLog
之间的外键关系,在我删除Test
行之后,SQLAlchemy试图更新所有该测试的审计日志,使其具有NULL
entityId
。我不希望它这样做;我希望SQLAlchemy不要使用审计日志。如何告诉SQLAlchemy允许其entityId
与任何Test.id
不连接的审核日志存在?
我试着从我的表中删除ForeignKey
,但是我仍然希望能够说myTest.audits
,并获取测试的所有审计日志,SQLAlchemy抱怨说不知道如何连接Test
和TestAuditLog
。当我在relationship
上指定了primaryjoin
时,它抱怨没有ForeignKey
或ForeignKeyConstraint
与列。
以下是我的模特:
class TestAuditLog(Base, Common):
__tablename__ = u'TEST_AUDIT_LOG'
entityId = Column(u'AL_TEST_ID', INTEGER(), ForeignKey(u'TEST.TS_TEST_ID'),
nullable=False)
...
class Test(Base, Common):
__tablename__ = u'TEST'
id = Column(u'TS_TEST_ID', INTEGER(), primary_key=True, nullable=False)
audits = relationship(TestAuditLog, backref="test")
...
下面是我如何尝试删除一个测试,同时保持其审核日志的完整性,它们的entityId
:
test = Session.query(Test).first()
Session.begin()
try:
Session.add(TestAuditLog(entityId=test.id))
Session.flush()
Session.delete(test)
Session.commit()
except:
Session.rollback()
raise
可以通过以下方法解决此问题:
RDBMS
级别和SA级别都没有ForeignKey
下面完整工作的代码片段应该给您一个想法(
code
中突出显示了点):另一个选项是复制FK中使用的列,并使用
ON CASCADE SET NULL
选项使FK列可以为空。这样,您仍然可以使用此列检查已删除对象的审核跟踪。相关问题 更多 >
编程相关推荐