比较PonyORM中的实体实例

时间:2018-06-18 07:10:37

标签: ponyorm

我正在尝试比较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中检索时,具有相同主键测试且具有相同且相等的实体。

  1. 这种行为背后的理由是什么? (来自docs:如果具有指定主键的对象已经加载到db_session()缓存中,Pony将从缓存中返回对象而不向数据库发送查询。这解释了结果身份测试。我仍然期望在测试1和2中看到相等。)

  2. 测试相等性的推荐方法是什么(比较主键除外)?

1 个答案:

答案 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