2015-11-06 46 views
1

我在嘗試更新使用外鍵作爲主鍵一部分的行時遇到問題。這裏有一個簡單情況:SQLAlchemy:將表數據與外鍵合併

class Foo(Base): 
    __tablename__ = 'foo_table' 
    foo_id = Column(Integer, primary_key=True) 
    bar_id = Column(Integer, ForeignKey('bar_table.bar_id'), primary_key=True) 
    foo_data = Column(String(255)) 

    bar = relationship('Bar', backref='foos', foreign_keys=[bar_id]) 

class Bar(Base): 
    __tablename__ = 'bar_table' 
    bar_id = Column(Integer, primary_key=True) 

首先我將創建爲foo_table的條目:

f = Foo() 
f.foo_id = 1 
f.foo_data = 'Foo Data' 

現在,我將在bar_table創建行和關聯兩個:

b = Bar() 
f.bar = b 

太棒了!我們將添加f到我們的會議,並承諾:

session.add(f) 
session.commit() 

現在假裝我們碰上與同foo_idFoo另一個實例,並與同一Bar,但也有一些新的數據:

f = Foo() 
f.foo_id = 1 
f.foo_data = 'NEW Foo Data' 
f.bar = b 

很好!這一直髮生,對吧?我會用session.merge()代替session.add()剛剛更新的foo_table的信息:

session.merge(f) 

但是,這不是很好!代碼中斷,我得到的回溯:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1689, in merge 
    self._autoflush() 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1282, in _autoflush 
    self.flush() 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 2004, in flush 
    self._flush(objects) 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 2122, in _flush 
    transaction.rollback(_capture_exception=True) 
    File "/Library/Python/2.7/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__ 
    compat.reraise(exc_type, exc_value, exc_tb) 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 2086, in _flush 
    flush_context.execute() 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 373, in execute 
    rec.execute(self) 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 532, in execute 
    uow 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/persistence.py", line 149, in save_obj 
    base_mapper, states, uowtransaction 
    File "/Library/Python/2.7/site-packages/sqlalchemy/orm/persistence.py", line 301, in _organize_states_for_save 
    state_str(existing))) 
sqlalchemy.orm.exc.FlushError: New instance <Foo at 0x10a804590> with identity key (<class 'test.Foo'>, (1, 1)) conflicts with persistent instance <Foo at 0x1097a30d0> 

有誰知道爲什麼此更新失敗?

回答

1

我不確定這是否有一個非常好的答案...我已經結束了查詢,以確定我是否正在處理新數據。

因此,任何時候,我創建的Foo一個新實例:

old_foo = session.query(Foo).filter(Foo.id == id).all() 
if old_foo: 
    foo = old_foo[0] 
else: 
    foo = Foo() 

這似乎並不理想,但我還沒有找到另一種解決方案,工程。