1

I am trying to compare PonyORM entity instances for identity/equality. Consider the following code, using the estore example database:

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

Entities with the same primary key test as identical and equal if and only if retrieved in the same db_session.

  1. What is the rationale behind this behaviour? (From the docs: If object with the specified primary key was already loaded into the db_session() cache, Pony returns the object from the cache without sending a query to the database. This explains the result of the identity test. I would still expect to see equality in both test 1 and 2.)

  2. What is the recommended way to test for equality (other than comparing primary keys)?

4

1 回答 1

0

这种行为背后的原因是什么?

最初 Pony 期望您db_session只使用内部的对象。所以 - 一旦结束,你不应该使用这些对象db_session。为什么会这样 - 您可以将db_session其视为交易。因此,如果您使用两个不同db_sessions的对象,您将使用不同的事务,这意味着不能保证这两个对象在逻辑上是一致的。

为什么 Pony 允许你在之后使用对象db_session?因为有些开发者想把应用层和数据库层分开,然后渲染 HTML 模板db_session

其实 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
于 2018-06-22T11:29:58.967 回答