- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我的代码结构如下:
project
--app
----utils
------util.py
----__init__.py
----models.py
--tests
----__init__.py
在 tests/__init__.py 中,我有代码通过从 app/__init__.py 中导入来初始化应用程序(如果重要的话是 flask)和数据库 session 。我可以在 tests/__init__.py 中创建模型、查询和访问反向引用的实例。以下形式的代码工作正常:
objs = SomeModel.query.all()
for o in objs:
o.backref
但是,如果我这样做:
from utils.util import some_function
objs = SomeModel.query.all()
for o in objs:
some_function(o)
其中 some_function 只是访问一个 backref
def some_function(obj):
obj.backref
我收到类似 DetachedInstanceError: Parent instance <SomeModel at 0x2c1fe10> is not bound to a Session; lazy load operation of attribute 'backref' cannot proceed
的错误
阅读 sqlalchemy 文档表明我需要将对象重新关联到数据库 session 。我这样做了,它看起来很有效(即运行该函数不会因先前的错误而失败):
import db_session
def some_function(obj):
db_session.add(obj)
obj.backref
那么一个对象究竟是什么时候分离的呢?似乎只是将对象传递给另一个模块中的函数会将其从 session 中分离出来。对象是否不知道与其关联的 sqlalchemy session ?我试图避免做 db_session.add(obj)
这看起来像是很多样板代码。
最佳答案
我在自己工作时遇到了这个 similar question关于属性过期和实例分离。 univerio给了我一个很好的答案,并且根据我一直在学习的知识,我也许能够阐明您的问题。
在我的例子中,我创建、提交或回滚,然后关闭一个 Session
,所有这些都在单个 with...as...
子句的范围内,然后立即尝试访问我保存的实例(在您的示例中为 obj
)但在该 with
子句 的范围之外。发生的事情是 Session
在我尝试引用保存的对象之前关闭了。 默认情况下,在 SQLAlchemy 中,如果没有active Session
,则无法访问持久属性/对象,除非明确告知允许它。这是为了“保护”代码免于意外或不知不觉地使用过时/不正确的数据,方法是强制应用程序首先查询/检索更新的数据,这需要关联的Session
。所以在我的例子中,在提交后保持 Session
打开意味着对象可以使用 Session
来查询数据库,以防记录在第一次写入后被修改。
在您的情况下,用于通过 objs = SomeModel.query.all()
获取对象的 Session
在查询之后但在 obj.backref
被调用(虽然我不确定如何;我不知道 SomeModel
是什么,确切地说,我假设是 Flask 的一个构造,它包含一个Session
在其后台)。所以 obj
不再与数据库有连接,因此是“分离的”。通过将它添加到 db_session
,您允许 obj
重新建立与其源数据库的连接,通过它可以查询以检查更新的属性,因此它不再分离。
最后,值得一提的是,DetachedInstanceError
可以通过指定 obj
关联的原始 Session
而不是 来避免自动过期属性。如果 expiring obj
,则不会抛出错误,但 obj
仍会分离,这意味着当您调用 obj.backref
时,返回的值可能不正确/已过时。您在问题中询问了分离,但过期是一个相关但不完全相同的概念。
旁白 -- 如何设置 obj
不会过期: 在 Session
的初始化时
my_session = sessionmaker(expire_on_commit=False
sessionmaker
的初始化
my_sessionmaker = sqlalchemy.orm.sessionmaker(expire_on_commit=False)
甚至在 Session
已经实例化之后
my_session.expire_on_commit = False
关于python - sqlalchemy 对象如何分离?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19818082/
我正在尝试创建一个使用 UUID 作为主键的用户模型: from src.db import db # SQLAlchemy instance import sqlalchemy_utils impo
在 sqlalchemy 中,我试图合并表,然后使用 WHERE 和 ORDER_BY 创建别名 有点像 SELECT * FROM ( SELECT [TABLE_ONE].[SOME_ID]
我正在使用 SQL Alchemy(通过 Flask_sqlalchemy)将 Python 字典列表插入到 Postgres 数据库中。 其中一个表是所有唯一项目的列表(表 1),而第二个是与某个项
This source详细说明如何使用关联代理创建具有 ORM 对象值的 View 和对象。 但是,当我附加一个与数据库中现有对象匹配的值(并且所述值是唯一的或主键)时,它会创建一个冲突的对象,因此我
SQLAlchemy Core和SQLAlchemy ORM的目的有什么区别? 最佳答案 顾名思义,ORM是一个对象关系映射器:其目的是将数据库关系表示为Python对象。 核心是查询构建器。其目的是
带有ForeignKey的Column是否自动创建索引? 还是我需要手动添加index=True? some_field = Column(Integer, ForeignKey(SomeModel.
我有一个主数据库,每个客户自己的数据库连接存储在其中。 因此,每个客户端都使用2个db:main和它自己的db,必须确定其连接 对于每个http调用。我如何使用flask-sqlalchemy扩展名执
当我仅对类进行继承时,它才起作用 class User(Base): __tablename__ = ’users’ id = Column(Integer, primary_key=
从用户的角度来看,SQLAlchemy 的查询日志似乎有点过于冗长,有时甚至有点神秘: 2015-10-02 13:51:39,500 INFO sqlalchemy.engine.base.Engi
我正在尝试使用 wtforms.ext.sqlalchemy QuerySelectMultipleField 显示复选框列表,但我无法在 GET 的表单上显示模型数据。 这是我的models.py
我想为查询返回一个中继连接。使用标准的 graphene-sqlalchemy 你可以这样做: class Query(graphene.ObjectType): node = relay.N
我在 centos 7.5 虚拟机上部署了最新的 Airflow ,并将 sql_alchemy_conn 和 result_backend 更新到 postgresql 实例上的 postgres
我想将多个项目插入到一个表中,并在发生冲突时更新该表。这是我想出的以下内容 from sqlalchemy.dialects.postgresql import insert meta = MetaD
我有以下模型: class Item(Base): a = relationship() b = relationship() c = relationship() d
我有 presto 和 superset 设置。 presto 运行良好,可以通过命令访问: ./app/hadoop/setjdk8.sh;bin/presto-cli --server http:
我一直在寻找一种在 sqlalchemy 中使用 tsvector 的方法(就像 INTEGER 等其他方法一样),但到目前为止我还不清楚如何做到这一点。我读过可以使用 UserDefinedType
我正在使用 sqlalchemy(现在使用 sqlite,但稍后可能会改变)来构建一个数据库,其中插入的顺序和 rowids 很重要。我基本上有以下几点: class Message(Base):
给定一个对象,我想知道如何知道它是否是 sqlalchemy 映射模型的实例。 通常,我会使用 isinstance(obj, DeclarativeBase)。但是,在这种情况下,我没有可用的 De
我已经通读了查询文档,如果有办法从查询中获取表名,就看不到任何地方 - 例如如果我有 q = query(Users) ,我可以得到Users从 q 退出? 最佳答案 请注意,像您这样的事件简单查询可
我不确定如何定义create schema foo迁移?我的模型如下所示(我正在使用Flask-Migrate): class MyTable(db.Model): __tablename__
我是一名优秀的程序员,十分优秀!