带有连接的SQLAlchemy和Insertion

时间:2015-06-26 07:45:33

标签: python 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.id更新为1)。我也尝试使用session.refresh(file1, ['id']),但我收到了一个错误:

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

1 个答案:

答案 0 :(得分:2)

简单的答案是在将文件对象添加到会话后使用session.flush() - 这将使用其ID填充文件对象。

但是,既然你正在使用声明性的东西,你也可以利用关系,避免考虑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)