我需要对某些关键表进行一种“版本控制”,并试图以一种相当简单的方式实现它:
CREATE TABLE [dbo].[Address] (
[id] bigint IDENTITY(1, 1) NOT NULL,
[post_code] bigint NULL,
...
)
CREATE TABLE [dbo].[Address_History] (
[id] bigint NOT NULL,
[id_revision] bigint NOT NULL,
[post_code] bigint NULL,
...
CONSTRAINT [PK_Address_History] PRIMARY KEY CLUSTERED ([id], [id_revision]),
CONSTRAINT [FK_Address_History_Address]...
CONSTRAINT [FK_Address_History_Revision]...
)
CREATE TABLE [dbo].[Revision] (
[id] bigint IDENTITY(1, 1) NOT NULL,
[id_revision_operation] bigint NULL,
[id_document_info] bigint NULL,
[description] varchar(255) COLLATE Cyrillic_General_CI_AS NULL,
[date_revision] datetime NULL,
...
)
和每个表的插入/更新/删除上的一堆触发器,用于存储它的更改。
我的应用程序基于PyQt + sqlalchemy,当我尝试插入存储在版本化表中的实体时,sqlalchemy会触发错误:
The target table 'Heritage' of the DML statement cannot have
any enabled triggers if the statement contains
an OUTPUT clause without INTO clause.
(334) (SQLExecDirectW); [42000]
[Microsoft][ODBC SQL Server Driver]
[SQL Server]Statement(s) could not be prepared. (8180)")
我该怎么办?我必须使用sqlalchemy。 如果有人可以给我一个建议,我怎样才能在没有触发器的情况下实现版本控制,这很酷。
答案 0 :(得分:4)
您应该将'implicit_returning'设置为'False',以避免在SQLAlchemy生成的查询中使用“OUTPUT”(这应解决您的问题):
class Company(sqla.Model):
__bind_key__ = 'dbnamere'
__tablename__ = 'tblnamehere'
__table_args__ = {'implicit_returning': False} # http://docs.sqlalchemy.org/en/latest/dialects/mssql.html#triggers
id = sqla.Column('ncompany_id', sqla.Integer, primary_key=True)
...
答案 1 :(得分:1)
我似乎无法添加评论,因此添加了另一个答案。
这并不复杂,我建议它不如在您的域中放置1/2业务逻辑而在数据库触发器中放置另一半更不易碎。
就个人而言,我会编写自己的列表对象,并引用some_list_of_other_entities的历史列表,并在Remove和Add方法中保留历史记录。
这样,您的对象会自动更新,甚至可以将它们保存到您的ORM中。
public class ListOfOtherEntities : System.Collections.IEnumerable
{
// Add list stuff here...
public void Remove(MyEntity obj)
{
this.List.Remove(obj);
this.History.Add(new History("Added a object!");
}
public void Remove(MyEntity obj)
{
this.List.Remove(obj);
this.History.Add(new History("Removed a object!");
}
}
这样,您的对象在将它们保存到ORM之前会自动更新,而另一位查看代码的开发人员可以很容易地看到您所做的事情。
答案 2 :(得分:0)
这不会直接回答你的问题,但根据我使用触发器的经验会导致无尽的痛苦,所以不惜一切代价避免它们。如果您自己管理所有数据,那么简单的答案就是自己填充版本历史记录表。这也意味着您将所有业务逻辑集中在一个地方,这是一个奖励!