SQLalchemy:onupdate自动增量(服务器端)

时间:2016-01-23 11:14:25

标签: sqlalchemy flask-sqlalchemy

在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

3 个答案:

答案 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找到了比我更容易解决的方法。糟糕。