2016-01-23 18 views
1

在SQLAlchemy中,我在一個混合使用此聲明的屬性:SQLAlchemy的:的onupdate自動增量(服務器端)

@declared_attr 
def updated_seq(cls): return db.Column(db.BigInteger(), server_default=0) 

,我想辦一個的onupdate即SQL Server(而不是蟒蛇)自動遞增由1的值。如何做呢? TX

我爲實例的onupdate中尋找以下SQL語句等效:

UPDATE updated_seq=updated_seq+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 
+0

但這是增加了python,而不是由sql服務器,正確的?所以這不是原子 – ptou

+0

「Python增量」轉換爲SQL。您可以回顯SQL來確認。用您期望的SQL輸出和一系列事務澄清您的問題。 – jumbopap

+1

我回應了SQL,我看到'UPDATE updated_seq = value'(由python會話增加的值)。我正在尋找的是像'更新updated_seq = updated_seq + 1' – ptou

1

其實正確的無非是:

@declared_attr 
def updated_seq(cls): return db.Column(db.BigInteger(), server_default=0, onupdate=text('updated_seq + 1')) 
0

聽起來像是觸發器的工作。首先某處混入:

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找到了比我更容易的解決方案。哎呀。