簡體   English   中英

如何創建一個sqlalchemy列,其默認值等於主鍵?

[英]How can I create a sqlalchemy column whose default is to be equal to the primary key?

我有一堂課,看起來像這樣:

class Foo(Base):
    pk = Column(Integer, Sequence('foo'), primary_key=True)

我想創建另一個字段ref ,它默認等於新創建對象的pk 不幸的是,我使用的是Postgres,它具有一個非標准的nextval()函數 ,因此我不能簡單地將這兩列都默認設置為Sequence對象。

這是我當前的解決方案:

class Foo(Base):
    pk = Column(Integer, Sequence('foo'), primary_key=True)
    ref = Column(Integer, index=True, nullable=False, default=func.currval('foo'))

但是,這取決於兩件事:SQLAlchemy生成一個在ref之前帶有pk的INSERT語句, 以及 Postgres從左到右評估表達式(因此pk生成的nextval()調用始終發生在ref生成的currval調用之前)。

對於如何更好地做到這一點,我將不勝感激!

編輯:還有更多的解決方案,設置default=-1或類似的東西,並強制調用方更新ref字段。 對於SQLA / Postgres語義的更改而言,這更安全,更可靠,但對於類的客戶而言卻非常不便。

可以利用SQLAlchemy的ORM after_insert映射器事件:

from sqlalchemy import event

# Model from OP
class Foo(Base):
    pk = Column(Integer, Sequence('foo'), primary_key=True)
    ref = Column(Integer, index=True, nullable=False, default=-1)

    @staticmethod
    def fill_ref(mapper, connection, target):
        # Note: You cannot use ORM in the event callbacks
        connection.execute(mapper.mapped_table.update()
                                 .values(ref=target.pk))
                                 .where(table.c.pk==target.pk))

event.listen(Foo, 'after_insert', Foo.fill_ref)

我建議使用觸發器來設置該值。 盡管我自己尚未對此進行測試,但是您可以使觸發器激活AFTER INSERT,該觸發器讀取新行的PK值並使用該值更新ref列。 似乎有點類似於Postgresql插入觸發器來設置值,不同的是您希望觸發器在插入之后而不是之前。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM