如何在 sqlalchemy 模型中使用 hybrid_property 进行过滤以解码列中的值?
How to filter with hybrid_property in sqlaclhemy model to decode value from column?
我不明白如何使用 hybrid properties 或者它们的局限性是什么。
我有一个模型,其中列以 ascii 格式存储域名。其中一些是 idna 编码表示的,如 utf-8:
domain.com
xn--d1acufc.xn--p1ai # домен.рф
...
我想用一个界面过滤域名。通过 ASCII 字符串过滤没有什么困难,但是非 ascii 是另一回事。
我想将 "рф"
之类的子字符串传递给 filter_by_name()
并获得预期结果 - 在这种情况下使用 xn--d1acufc.xn--p1ai
的 1 条记录
class SomeModel(Base):
__tablename__ = "table"
name = Column(String(255))
@hybrid_property
def decoded_name(self):
return self.name.encode("utf-8").decode("idna")
@decoded_name.expression
def decoded_name(cls):
return cls.name.encode("utf-8").decode("idna")
@classmethod
def filter_by_name(cls, substring: str):
with sessionmaker.begin() as s:
query = s.query(SomeModel)
if substring.isascii():
condition = cls.name.like(f"%{substring}%")
else:
condition = cls.decoded_name.like(f"%{substring}%")
query = query.filter(condition)
return query.all()
购买我收到以下错误消息。看来我应该将 sqlclhemy func 与对应的 SQL 函数一起使用,但是...如果我需要 python 像 encode/decode 这样的例程怎么办?
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with SomeModel.name has an attribute 'encode'
定义表达式时:
@decoded_name.expression
def decoded_name(cls):
return cls.name.encode("utf-8").decode("idna")
您处于数据库级别,而不是 python 级别。所以你应该使用数据库操作员,但在你的情况下它可能很棘手甚至不可能。根据数据库的不同,您的实现会有所不同。对于 PostgreSQL,您可能应该使用 convert
函数:https://www.postgresql.org/docs/8.2/functions-string.html and maybe this idna extension (that should be installed in a database): https://github.com/dyninc/postgresql-idn。
然后你的表情看起来像这样:
@decoded_name.expression
def decoded_name(cls):
return func.idn_idna_encode(func.convert(cls.name, <one_of_utf-8_conversion_type>))
我不明白如何使用 hybrid properties 或者它们的局限性是什么。
我有一个模型,其中列以 ascii 格式存储域名。其中一些是 idna 编码表示的,如 utf-8:
domain.com
xn--d1acufc.xn--p1ai # домен.рф
...
我想用一个界面过滤域名。通过 ASCII 字符串过滤没有什么困难,但是非 ascii 是另一回事。
我想将 "рф"
之类的子字符串传递给 filter_by_name()
并获得预期结果 - 在这种情况下使用 xn--d1acufc.xn--p1ai
class SomeModel(Base):
__tablename__ = "table"
name = Column(String(255))
@hybrid_property
def decoded_name(self):
return self.name.encode("utf-8").decode("idna")
@decoded_name.expression
def decoded_name(cls):
return cls.name.encode("utf-8").decode("idna")
@classmethod
def filter_by_name(cls, substring: str):
with sessionmaker.begin() as s:
query = s.query(SomeModel)
if substring.isascii():
condition = cls.name.like(f"%{substring}%")
else:
condition = cls.decoded_name.like(f"%{substring}%")
query = query.filter(condition)
return query.all()
购买我收到以下错误消息。看来我应该将 sqlclhemy func 与对应的 SQL 函数一起使用,但是...如果我需要 python 像 encode/decode 这样的例程怎么办?
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with SomeModel.name has an attribute 'encode'
定义表达式时:
@decoded_name.expression
def decoded_name(cls):
return cls.name.encode("utf-8").decode("idna")
您处于数据库级别,而不是 python 级别。所以你应该使用数据库操作员,但在你的情况下它可能很棘手甚至不可能。根据数据库的不同,您的实现会有所不同。对于 PostgreSQL,您可能应该使用 convert
函数:https://www.postgresql.org/docs/8.2/functions-string.html and maybe this idna extension (that should be installed in a database): https://github.com/dyninc/postgresql-idn。
然后你的表情看起来像这样:
@decoded_name.expression
def decoded_name(cls):
return func.idn_idna_encode(func.convert(cls.name, <one_of_utf-8_conversion_type>))