sqlalchemy @hybrid_property v @property,@hybrid_method v @classmethod

Posted

技术标签:

【中文标题】sqlalchemy @hybrid_property v @property,@hybrid_method v @classmethod【英文标题】:sqlalchemy @hybrid_property v @property, @hybrid_method v @classmethod 【发布时间】:2021-01-14 13:49:00 【问题描述】:

我有一个模型(我将其用作抽象基类),它具有一些常用方法和属性。

SQLAlchemy 允许使用 @hybrid_property@hybrid_method 创建属性和方法,但标准的 @property@classmethod@staticmethod 装饰器可以为我提供我想要的结果。

与标准 python 装饰器相比,使用 SQLA 装饰器有什么优点和缺点吗?

什么时候应该使用或不应该使用 SQLA 装饰器?

【问题讨论】:

【参考方案1】:

hybrid 提供了一个在 Python 中都适用的表达式 级别以及 SQL 表达式级别

我们来看一个例子:

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    firstname = Column(String(50))
    lastname = Column(String(50))

    @hybrid_property
    def fullname(self):
        return self.firstname + ' ' + self.lastname

    @property
    def long_name(self):
        return self.firstname + ' ' + self.lastname


session.add(User(firstname='Brendan', lastname='Simon'))
session.commit()
# error
# print(session.query(User).filter(User.long_name == 'Brendan Simon').first().id)
# works fine because @hybrid_property
print(session.query(User).filter(User.fullname == 'Brendan Simon').first().id)

您还可以使用@fullname.expression 自定义SQL expression

什么时候应该使用或不应该使用 SQLA 装饰器?

我想你会知道什么时候需要它。例如,您可以将其用于快速别名:

class MetaData(Base):
    __tablename__ = 'meta_data'
    system_field = Column(String(20))  # a lot of calculations and processing in different places
    # a lot of fields ...

有一天,system_field 曾(或将要)重命名为 new_field(不管为什么、谁和何时——只是事实)。您可以执行以下操作作为快速解决方案:

@hybrid_property
def new_field(self):
    return self.system_field

@new_field.setter
def new_field(self, value: str):
    self.system_field = value

# data from somewhere...
# data = 'new_field': 'default', other fields...
# will works fine + in other places will work as `system_field` with old sql queries
process_meta(MetaData(**data))

所以这是一个非常好的功能,但是如果你在考虑是否需要它,那么你肯定不需要它。

【讨论】:

好的。因此,总而言之,最好的方法是使用标准的 python 装饰器,然后在/如果需要时转移到 SQLA 装饰器。大概是为了过滤目的。

以上是关于sqlalchemy @hybrid_property v @property,@hybrid_method v @classmethod的主要内容,如果未能解决你的问题,请参考以下文章

flask-sqlalchemy 和sqlalchemy的区别

flask-sqlalchemy

sqlalchemy.exc.NoSuchModuleError:无法加载插件:sqlalchemy.dialects:postgres

SQLAlchemy 是不是从同一连接重置 SQLAlchemy 会话之间的数据库会话?

SQLAlchemy使用笔记--SQLAlchemy ORM

SQLAlchemy -- Python的SQLAlchemy和ORM