在SQLalchemy中,我在mixin中使用了这个声明的属性:
@declared_attr
def updated_seq(cls): return db.Column(db.BigInteger(), server_default=0)
我想做一个onupdate,其中sql server(而不是python)自动递增1的值。怎么做到呢? TX
我在onupdate期间寻找以下sql等效语句:
UPDATE updated_seq=updated_seq+1
答案 0 :(得分:2)
实际上正确的是:
@declared_attr
def updated_seq(cls): return db.Column(db.BigInteger(), server_default=0, onupdate=text('updated_seq + 1'))
答案 1 :(得分:0)
您可以使用递增updated_seq
的事件侦听器来处理这种情况。
class Mixin(object):
@declared_attr
def updated_seq(cls):
return Column(BigInteger, server_default='0')
class Person(Base, Mixin):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(Text)
@event.listens_for(Person, 'before_update')
def increment_seq(mapper, connection, target):
target.updated_seq += 1
>>> p = Person(name="foo")
>>> session.add(p)
>>> session.commit()
>>> p = session.query(Person).first()
>>> p.updated_seq
0
>>> p.name = "bar"
>>> session.commit()
>>> p = session.query(Person).first()
>>> p.updated_seq
1
答案 2 :(得分:0)
听起来像触发器的工作。首先是mixin:
class Mixin(object):
@declared_attr
def updated_seq(cls):
return Column(BigInteger, server_default='0')
然后在启动文件或脚本上,无论你喜欢哪里(我都想不出任何真正优雅的东西)。这是PSQL中的一个解决方案
# import Mixin
# import sqlalchemy engine
for class_ in Mixin.__subclasses__:
engine.execute('''
CREATE OR REPLACE FUNCTION %{tablename}s_increment() RETURNS TRIGGER AS $$
BEGIN
NEW.updated_seq := OLD.updated_seq + 1 WHERE id = OLD.id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER %{tablename}s_increment_trigger BEFORE UPDATE ON %{tablename}s
FOR EACH ROW EXECUTE PROCEDURE %{tablename}s_increment();
``` % {tablename: class_.__tablename__}
您可能需要检查我的SQL,因为它已经有一段时间了,这是未经测试的。但无论如何,它会在您的数据库中创建检测并自动增加该行的触发器。缺点是您需要手动删除任何丢失updated_seq列的触发器
编辑:看起来OP找到了比我更容易解决的方法。糟糕。