Приложение My Flask-Restful имеет несколько "объектов". В первой версии приложения это простые структуры данных без каких-либо действий, реализованных как диктовки или списки диктов.
Атрибуты этих "объектов" могут измениться. Я использую функцию генератора для отслеживания изменений, а затем предупреждаю веб-клиентов через сервер-отправленные события (SSE). Это работает, поддерживая "старую" копию объекта, подлежащего отслеживанию, и сравнивая его с последним состоянием.
В следующей версии приложения я заполняю "объекты" из SQLite DB, используя SQLAlchemy. Объекты теперь реализованы как декларативные классы SQLAlchemy или списки таких классов.
Чтобы сравнить "старые" и "новые" экземпляры на основе равенства атрибутов, мне пришлось добавить переопределение __eq__
в
мои объекты SQLAlchemy. т.е. экземпляры считаются равными/неизменными, когда атрибуты имеют одинаковые значения.
(Я разместил пример кода внизу этого вопроса).
Технически это работает, но вызывает некоторые архитектурные сигнальные колокола: "Я плыву в неправильном направлении?"
a) Если я добавлю __eq__
и __ne__
переопределяет объекты SQAlchemy, может ли это вызвать SQLAlchemy проблему, когда я позже захочу
для повторного сохранения объектов обратно в базу данных?
b) Насколько далеко до моего приложения должны появляться объекты SQLAlchemy: существует ли "питонская лучшая практика"? То есть нормально или нормально распространять объекты SQLAlchemy с бизнес-логикой/поведением, не связанными с постоянством БД (например, отслеживание изменений); или они должны использоваться только как простые DTO между базой данных и сервером, с бизнес-логикой в других объектах?
Примечание: мне ясно, что данные, представленные клиентам через REST apis и SSE, должны быть абстрагированы от деталей реализации на веб-сервере и БД, так что это не является частью этого вопроса.
sqlalchemy id равенство против равенства ссылок https://codereview.stackexchange.com/info/93511/data-transfer-objects-vs-entities-in-java-rest-server-application http://www.mehdi-khalili.com/orm-anti-patterns-part-4-persistence-domain-model/
class EqualityMixin(object):
# extended from the concept in :
# https://stackoverflow.com/info/390250/elegant-ways-to-support-equivalence-equality-in-python-classes
def __eq__(self, other):
classes_match = isinstance(other, self.__class__)
a, b = deepcopy(self.__dict__), deepcopy(other.__dict__)
#compare based on equality our attributes, ignoring SQLAlchemy internal stuff
a.pop('_sa_instance_state', None)
b.pop('_sa_instance_state', None)
attrs_match = (a == b)
return classes_match and attrs_match
def __ne__(self, other):
return not self.__eq__(other)