【问题标题】:Inserting objects and using ids in SqlAlchemy在 SqlAlchemy 中插入对象和使用 id
【发布时间】:2012-10-07 19:45:30
【问题描述】:

我有一个表并用对象列表填充它,然后我需要使用他们的 ID,但我得到了一个

Instance 未绑定到 Session;属性刷新操作无法进行

错误。

我正在用对象填充一个列表并将其发送到一个函数以一次插入所有对象。然后我尝试使用 ID。

这是我的全部插入功能:

def insertlocations(locationlist):
    session.add_all(locationlist)
    session.commit()
    session.close()

然后我尝试获取 ID:

insertlocations(neighbourhoodlist)
session.flush(neighbourhoodlist)
for neighbourhood in neighbourhoodlist:
    print neighbourhood.locationid

顺便说一句,会话是全局的。需要更多信息吗?

数据已插入,正如我在 MySQL 表中查看的那样。

【问题讨论】:

    标签: python mysql sqlalchemy


    【解决方案1】:

    您的问题很可能是您已经在insertlocations() 函数中close() 会话。

    当您随后访问neighbourhood.locationid 时,会话将关闭,并且neighbourhood 对象不再绑定到会话。

    例如,这应该可以工作:

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String
    from sqlalchemy.orm import sessionmaker
    
    engine = create_engine('sqlite:///example.db')
    engine.echo = True
    Base = declarative_base()
    
    class Location(Base):
        __tablename__ = 'locations'
    
        locationid = Column(Integer, primary_key=True)
        name = Column(String)
        address = Column(String)
    
        def __init__(self, name, address):
            self.name = name
            self.address = address
    
    
    Base.metadata.create_all(engine)
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    def insertlocations(locationlist):
        session.add_all(locationlist)
        session.commit()
    
    
    loc1 = Location('loc1', 'Foostreet 42')
    loc2 = Location('loc2', 'Barstreet 27')
    
    neighbourhoodlist = [loc1, loc2]
    
    insertlocations(neighbourhoodlist)
    for neighbourhood in neighbourhoodlist:
        print neighbourhood.locationid
    
    session.close()
    
    • session.close() 移出您的函数,并在使用完该会话后执行此操作。
    • 放弃 session.flush(),不需要它,因为您在添加对象时已经提交了会话。

    【讨论】:

    • 也许,但我不能在不关闭的情况下离开会话,这会导致许多打开的连接。有什么建议吗?
    • @vardars 当然。完成对它们的操作后关闭它们,例如在您的for/print 循环之后。
    • 感谢您的出色榜样和帮助。实际上我在其他情况下使用了 insertlocations 功能,这些情况不需要使用 id,直到这种情况下我都在使用它。所以如果我从插入位置中删除 session.close(),我需要更新所有的函数调用代码。我决定创建另一个不关闭会话的函数,我将调用它,或者直接使用 add_all()。我正在尝试通过做小例子来学习,也许将来我会在更大的项目中使用它们。再次感谢您的帮助,非常感谢。
    • @vardars 如果出于某种原因您想提前关闭会话,但仍然可以读取某些对象的属性,请查看session.expunge()。还有一个answer on SO 有一个如何使用它的例子。
    • 您应该保持会话打开,以实现包含一系列操作的一致跨度。理想情况下,这种创建/关闭模式应该在您的应用程序中建立一次,作为所有操作的框架。这与在整个应用程序中散布许多 ad-hoc/冗余打开/关闭块形成对比。最近修改的文档部分提供了这方面的一些背景信息:docs.sqlalchemy.org/en/latest/orm/…
    猜你喜欢
    • 2013-06-04
    • 2023-03-08
    • 2021-09-27
    • 2022-07-07
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多