Python 比较SQLAlchemy对象实例的属性相等性

Python 比较SQLAlchemy对象实例的属性相等性,python,sqlalchemy,Python,Sqlalchemy,我的Flask Restful应用程序有许多“对象”。在应用程序的第一个版本中,这些是简单的数据结构 没有行为,实现为DICT或DICT列表 这些“对象”的属性可以更改。我使用生成器函数跟踪更改,然后通过服务器发送事件(SSEs)向web客户端发出警报。 其工作原理是维护要跟踪的对象的“旧”副本,并将其与最新状态进行比较 在下一个版本的应用程序中,我使用SQLAlchemy从SQLite数据库填充“对象”。 这些对象现在实现为SQLAlchemy声明类或此类类的列表 为了仅根据属性的相等性比较“

我的Flask Restful应用程序有许多“对象”。在应用程序的第一个版本中,这些是简单的数据结构 没有行为,实现为DICT或DICT列表

这些“对象”的属性可以更改。我使用生成器函数跟踪更改,然后通过服务器发送事件(SSEs)向web客户端发出警报。 其工作原理是维护要跟踪的对象的“旧”副本,并将其与最新状态进行比较

在下一个版本的应用程序中,我使用SQLAlchemy从SQLite数据库填充“对象”。 这些对象现在实现为SQLAlchemy声明类或此类类的列表

为了仅根据属性的相等性比较“旧”和“新”实例,我必须在 我的SQLAlchemy对象。i、 e.当属性值相同时,实例被视为相等/不变。 (我已经在这个问题的底部发布了示例代码)

从技术上讲,这是可行的,但也给建筑界敲响了警钟:我是不是走错了方向

a) 如果我向SQAlchemy对象添加
\uuuuu eq\uuuuu
\uuu ne\uuuuuuu
覆盖,这是否会在我以后需要时导致SQLAlchemy出现问题 要将对象重新持久化回数据库

b) SQLAlchemy对象应该深入到我的应用程序的什么程度:有“pythonic最佳实践”吗?i、 e.使用与DB持久性无关的业务逻辑/行为(如跟踪更改)扩展SQLAlchemy对象是否可以/正常;或者它们应该只作为数据库和服务器之间的简单DTO使用,而业务逻辑在其他对象中

注意:我很清楚,通过RESTAPI和SSE呈现给客户机的数据应该从web服务器和DB中的实现细节中抽象出来,因此这不是这个问题的一部分


我将深入研究基类后面发生的事情,以表明
\uuuuuueq\uuuu
\uuune\uuuuuu
重写是正确的。当您通过调用
声明性_Base()
来实例化
Base
类时,它是在幕后使用元类来设置它的(阅读此说明可能有助于更好地理解它涉及的原因)。它进行一些可配置的设置,比如向
基本类添加自定义构造函数,并设置如何将其从对象映射到表

self.cls.__mapper__ = mp_ = mapper_cls(
        self.cls, # cls is your model
        self.local_table,
        **self.mapper_args # the columns you have defined
    )
declarative_base()
然后将返回
DeclarativeMeta
元类的新
base
类实例。这里涉及元类的全部原因是,当您创建扩展
基的类时,它会将其映射到表。如果您沿着这条路径走一小段路,就会看到它是如何将您在对象上声明的列映射到表的

self.cls.__mapper__ = mp_ = mapper_cls(
        self.cls, # cls is your model
        self.local_table,
        **self.mapper_args # the columns you have defined
    )
虽然实际的映射程序看起来非常复杂和低级,但在这个阶段,它使用的是主键和列,而不是实际的对象实例。但是,这并不能证实它从未被使用过,所以我查看了
=
的用法=,未发现任何问题原因


至于你的第二个问题,我只能提出我自己的看法——我在过去曾多次在谷歌上搜索过这个问题,但在“金本位”SQL炼金术的使用方面并没有发现太多。到目前为止,我已经在几个项目中使用了SQL Alchemy,感觉您对对象的使用可以扩展到您仍然可以合理地抽象出
会话
生命周期的范围。在我看来,炼金术的“魔力”似乎已经足够从模型本身抽象出来了,当会话处理得好时,它们与数据层的距离就足够远了,这样就不会觉得类中的业务逻辑会成为障碍。

是的,你在这方面走错了方向。深入的比较将是非常缓慢和容易出错的。完成这项工作,并为希望包含此功能的每个对象编写显式的
\uuuuuu eq\uuuuu()
例程,比较您单独关心的实际属性。在上面的代码中,您可能希望对称检查:类匹配=isinstance(其他,self.\uuuuuuuu class\uuuuu)和isinstance(self,其他.\uuuuuuu class\uuu)