2015-06-26 73 views
0

我想填充一個數據庫,該數據庫具有與另一個表的一對多關係的表。一個基本的例子是:SQLAlchemy和插入連接

class File(Base): 
    __tablename__ = 'Files' 
    id = Column(Integer, primary_key=True) 
    title = ... 

class Package(Base): 
    __tablename__ = 'Package' 

    id = Column(Integer, primary_key=True) 
    file_id = Column(Integer, ForeignKey('Files.id'), nullable=False) 
    title = ... 

由於文件表是「獨立」我開始加入他們

file1 = File(title='...') 
file2 = File(title='...') 

session.add(file1) 
session.add(file2) 

然後我可以添加包,這是那裏的問題就來了:

pkg1 = Package(file_id = file1.id, title='pkg1') 
pkg2 = Package(file_id = file1.id, title='pkg2') 

session.add(pkg1) # will fail 
session.add(pkg2) # will fail too 

它失敗,因爲file1.idNone。目前爲防止這種情況發生,我在添加文件後提交數據庫。

我想如果有更好的方式在數據庫內插入數據,不需要提交。 (我用了一個提交,但是查詢也更新了file1.id1)。我還試圖用session.refresh(file1, ['id']),但我得到了一個錯誤:

sqlalchemy.exc.InvalidRequestError: Instance '<File at 0x34a5a70>' is not persistent within this Session 

回答

2

簡單的答案是使用session.flush()您已經添加了文件對象的會話之後 - 將與他們的IDS填充您的文件對象。

但是,由於您使用的是聲明性內容,所以您可以利用關係並避免必須考慮ID。

class File(Base): 
    __tablename__ = 'Files' 
    id = Column(Integer, primary_key=True) 
    title = ... 

class Package(Base): 
    __tablename__ = 'Package' 

    id = Column(Integer, primary_key=True) 
    file_id = Column(Integer, ForeignKey('Files.id'), nullable=False) 
    title = ... 

    file = relationship('File', backref='packages') 

file1 = File(title='...') 
# notice that we can now link the package to the file without having to think 
# about ids - we're thinking in terms of the _objects_ 
pkg1 = Package(title='pkg1', file=file1) 

# file1 will be automatically added 
session.add(pkg1) 
+0

非常好,修改它。刪除了我寫的一半代碼。奇蹟般有效。謝謝 – Setepenre