由于旧数据在数据库中不可用,但有些外部文件可用,所以我想创建一个SQLAlchemy对象,该对象包含从外部文件读取的数据,但如果执行session.flush()
,则不会写入数据库
我的代码如下:
try:
return session.query(Phone).populate_existing().filter(Phone.mac == ident).one()
except:
return self.createMockPhoneFromLicenseFile(ident)
def createMockPhoneFromLicenseFile(self, ident):
# Some code to read necessary data from file deleted....
phone = Phone()
phone.mac = foo
phone.data = bar
phone.state = "Read from legacy file"
phone.purchaseOrderPosition = self.getLegacyOrder(ident)
# SQLAlchemy magic doesn't seem to work here, probably because we don't insert the created
# phone object into the database. So we set the id fields manually.
phone.order_id = phone.purchaseOrderPosition.order_id
phone.order_position_id = phone.purchaseOrderPosition.order_position_id
return phone
除了在应用程序稍后执行的session.flush()
上,SQLAlchemy尝试将创建的Phone对象写入数据库(幸运的是,这没有成功,因为电话.状态超出数据类型允许的长度),这将中断发出刷新的函数。在
有什么方法可以阻止SQLAlchemy尝试编写这样的对象吗?在
更新
但我什么也没发现
^{pr2}$在Elixir文档中(也许您可以提供一个链接?),在我看来,它值得一试(我更希望使用一种方法来防止编写单个实例,而不是整个实体)。在
起初,这个语句似乎没有效果,我怀疑我的SQLAlchemy/Elixir版本太旧,但是后来我发现到PurchaseOrderPosition实体(我没有修改)的连接是用
phone.purchaseOrderPosition = self.getLegacyOrder(ident)
导致再次写入phone对象。如果我把这句话删掉,一切都会好起来的。在
但我也遇到了一个类似的问题,在我的sqlalchemy中,它是由backref上的级联引起的:
http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html#backref-cascade
在backrefs上关闭它,这样您就必须显式地向会话添加内容
你必须这么做
以防止您实例化的
Entity
实例自动添加到会话中。理想情况下,这应该尽早在代码中完成。您也可以通过using_mapper_options(save_on_init=False)
-有关详细信息,请参阅Elixir文档。在更新:
请参阅灵丹妙药邮件列表上的this post,说明这就是解决方案。在
此外,正如Ants Aasma指出的,您可以在Elixir关系中使用级联选项来设置SQLAlchemy中的级联选项。有关详细信息,请参见this page。在
默认情况下,sqlalchemy不会。在
考虑以下自包含的示例代码。在
所以我不确定在会话中添加实例是什么意思。通常,您必须手动调用} 将其从会话中删除。在
s.add(u)
使其转到会话。我不熟悉长生不老药,所以也许这是一些长生不老药的诡计。。。也许您可以使用^{相关问题 更多 >
编程相关推荐