我正在尝试比较PonyORM实体实例的身份/相等性。请使用estore
示例数据库考虑以下代码:
from pony.orm import *
from pony.orm.examples.estore import *
# Test 1
with db_session:
a = Customer[1]
b = Customer[1]
print(a is b, a == b) # True True
# Test 2
with db_session:
a = Customer[1]
with db_session:
b = Customer[1]
print(a is b, a == b) # False False
当且仅当在同一db_session
中检索时,具有相同主键测试且具有相同且相等的实体。
这种行为背后的理由是什么? (来自docs:如果具有指定主键的对象已经加载到db_session()缓存中,Pony将从缓存中返回对象而不向数据库发送查询。这解释了结果身份测试。我仍然期望在测试1和2中看到相等。)
测试相等性的推荐方法是什么(比较主键除外)?
答案 0 :(得分:0)
此行为背后的原理是什么?
最初,Pony希望您仅使用db_session
内部的对象。因此-db_session
一旦结束,就不应使用这些对象。为什么会这样-您可以将db_session
视为交易。因此,如果使用两个不同的db_sessions
,则使用不同的事务,这意味着无法保证这两个对象在逻辑上是一致的。
为什么Pony允许您在db_session
之后使用对象?因为有些开发人员想将应用程序层与数据库层分开,并在db_session
完成后呈现HTML模板。
实际上,Pony认为正确的方法是在db_session
内呈现模板,但要求太高,因此Pony允许这样做。但是无论如何,将另外两个db_sessions
中的对象混合在一起是完全错误的方式,Pony不想让您这样做。
推荐的平等测试方法是什么?
如果您仍然想比较来自不同db_sessions的对象,我建议您使用这样的函数
def equals(a, b):
if isinstance(a, pony.orm.core.Entity):
return type(a) == type(b) and a.get_pk() == b.get_pk()
return a == b
with db_session:
a = Customer[1]
with db_session:
b = Customer[1]
print(a is b, a == b, equals(a, b)) # False, False, True