[英]Sqlalchemy and PostgreSql: how to set primary key manually without conflicts in future?
我有這樣的表:
class Tag(Base):
__tablename__ = 'tag'
id = Column(Integer, primary_key=True)
name = Column(Unicode(50), nullable=False)
def __init__(self, name):
self.name = name
Supose表是空的。 比我以這種方式插入一些數據:
t = Tag('first tag')
t.id = 2
dbsession.add(t)
dbsession.commit()
沒關系:我的postgresql表中有一行,id = 2。
t = Tag('second tag')
dbsession.add(t)
dbsession.commit()
比我有2行:{id:1,名稱:'第二個標簽'}和{id:2,名稱:'first_tag'}
下一步(最后一步):
t = Tag('third tag')
dbsession.add(t)
dbsession.commit()
IntegrityError :(IntegrityError)重復鍵值違反唯一約束“tag_pkey”
(它想要創建id = 2的行,但它已經與第一個標簽一起使用了)
是否有可能以某種方式對postgres說:如果這樣的pkey存在,請嘗試下一步直到它可用?
使用轉儲時非常有用。
提前致謝!
我不知道有什么安全,有效的方法來做你想做的事。 您應該自己選擇是自己定義密鑰還是使用生成的密鑰並堅持使用一種策略或另一種策略。
如果你不介意可怕的並發,你可以LOCK TABLE thetable
setval
,做你的工作,在你插入的內容之后將表的標識符序列設置為下一個空閑值,並commit
釋放鎖。 但是,這仍然會導致顯式調用nextval
(如許多ORM)的應用程序出現問題,而不是讓數據庫通過從?INSERT
列列表中省略它或明確地將其命名為DEFAULT
定義值。
否則,您可以使用您的代碼(或PL / PgSQL輔助函數)在重試循環中執行插入操作,該循環會增加密鑰並在獲得完整性錯誤時再次嘗試。 如果您需要執行的操作不僅僅是每個事務的一個插入,那么此策略將不起作用。 此外,在SERIALIZABLE
隔離模式下,我認為你無法使用PL / PgSQL,你必須使用客戶端重試循環來處理序列化失敗。
這是一個糟糕的主意。 一致地使用應用程序定義的鍵,或者一致地使用數據庫定義的鍵。 不要混淆兩者。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.