У меня есть модель/таблица Test
и модель/таблица TestAuditLog
, использующая SQLAlchemy и SQL Server 2008. Связь между ними Test.id == TestAuditLog.entityId
, причем один тест имеет много журналов аудита. TestAuditLog
предназначен для сохранения истории изменений строк в таблице Test
. Я хочу отслеживать, когда удаляется Test
, но у меня возникают проблемы с этим. В SQL Server Management Studio я установил для параметра FK_TEST_AUDIT_LOG_TEST
отношение Enforce Foreign Key Constraint "значение" Нет", считая, что это позволит существовать строка TestAuditLog
с entityId
, который больше не подключается к какому-либо Test.id
, потому что Test
был удален. Однако, когда я пытаюсь создать TestAuditLog
с SQLAlchemy, а затем удалю Test
, я получаю сообщение об ошибке:
(IntegrityError) ( "23000", "[23000] [Microsoft] [Драйвер SQL-сервера ODBC] [SQL Server] Невозможно вставить значение NULL в столбец" AL_TEST_ID ", таблицу" TEST_AUDIT_LOG ", столбец не допускает нулей. UPDATE не работает. (515) (SQLExecDirectW); [01000] [Microsoft] [драйвер SQL-сервера ODBC] [SQL Server] Оператор завершен. (3621)" ) u'UPDATE [TEST_AUDIT_LOG] SET [AL_TEST_ID] =? WHERE [TEST_AUDIT_LOG]. [AL_ID] =? ' (Нет, 8)
Я думаю из-за отношения внешнего ключа между Test
и TestAuditLog
, после того как я удалю строку Test
, SQLAlchemy пытается обновить все журналы тестового аудита, чтобы иметь NULL
entityId
. Я не хочу, чтобы это делалось; Я хочу, чтобы SQLAlchemy оставила только журналы аудита. Как я могу сказать SQLAlchemy, чтобы разрешить существование журналов аудита, чей entityId
не соединяется ни с одним Test.id
?
Я попробовал просто удалить ForeignKey
из своих таблиц, но я все равно могу сказать myTest.audits
и получить все журналы аудита тестирования, а SQLAlchemy жаловалась на то, что не знаю, как присоединиться к Test
и TestAuditLog
. Когда я тогда указал primaryjoin
на relationship
, он ворчал о том, что не имеет 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