Python SQLALCHEMY忽略查询上的重音符号

Python SQLALCHEMY忽略查询上的重音符号,python,sqlalchemy,flask,diacritics,Python,Sqlalchemy,Flask,Diacritics,考虑到我的用户可以将数据保存为“café”或“cafe”,我需要能够使用不区分重音的查询来搜索该字段 我已经找到了,但是我不知道是否有可能在sqlalchemy上实现类似的东西 我使用的是PostgreSQL,所以如果解决方案是针对这个数据库的,对我来说是很好的。如果它是通用的解决方案,那就更好了 感谢您的帮助。一个简单且与数据库无关的解决方案是编写可以有两次重音的字段,一次带重音,一次不带重音。然后,您可以在未登录版本上进行搜索 要生成字符串的无注释版本,可以使用 要在插入或更新记录时自动将未

考虑到我的用户可以将数据保存为“café”或“cafe”,我需要能够使用不区分重音的查询来搜索该字段

我已经找到了,但是我不知道是否有可能在sqlalchemy上实现类似的东西

我使用的是PostgreSQL,所以如果解决方案是针对这个数据库的,对我来说是很好的。如果它是通用的解决方案,那就更好了


感谢您的帮助。

一个简单且与数据库无关的解决方案是编写可以有两次重音的字段,一次带重音,一次不带重音。然后,您可以在未登录版本上进行搜索

要生成字符串的无注释版本,可以使用

要在插入或更新记录时自动将未登录版本分配给数据库,可以使用
定义中的
default
onupdate
子句。例如,使用炼金术,您可以执行以下操作:

from unidecode import unidecode
def unaccent(context):
    return unidecode(context.current_parameters['some_string'])

class MyModel(db.Model):
    id = Column(db.Integer, primary_key=True)
    some_string = db.Column(db.String(128))
    some_string_unaccented = db.Column(db.String(128), default=unaccent, onupdate=unaccent, index=True)
for place in session.query(Place).filter(unaccent(Place.name) == "cafe").all():
    print place.name
请注意,我是如何只为uncented字段编制索引的,因为这是将进行搜索的字段

当然,在您可以搜索之前,您还必须取消输入您正在搜索的值。例如:

def search(text):
    return MyModel.query.filter_by(some_string_unaccented = unaccent(text)).all()

如果需要,您可以将相同的技术应用于全文搜索。

首先在PostgreSQL中安装uncess扩展:
创建扩展uncent

接下来,在Python中声明SQL函数
uncent

from sqlalchemy.sql.functions import ReturnTypeFromArgs

class unaccent(ReturnTypeFromArgs):
    pass
然后像这样使用它:

from unidecode import unidecode
def unaccent(context):
    return unidecode(context.current_parameters['some_string'])

class MyModel(db.Model):
    id = Column(db.Integer, primary_key=True)
    some_string = db.Column(db.String(128))
    some_string_unaccented = db.Column(db.String(128), default=unaccent, onupdate=unaccent, index=True)
for place in session.query(Place).filter(unaccent(Place.name) == "cafe").all():
    print place.name

如果表很大,请确保索引正确,否则将导致全表扫描。

成功了!我不得不使用下面Miguel在搜索字符串上建议的unidecode。结果是这样的:
session.query(Place).filter((uncent(Place.name).ilike(string))
。它也忽略了案例。谢谢!谢谢!虽然我最终使用了user2716201的方法,但我也在输入字符串上使用了您的
unidecode
建议。很抱歉,我无法对你的答案进行投票,显然我目前没有足够的声誉。我对这个解决方案有点困惑。
uncent
功能在
search
功能中是如何工作的?它返回
AttributeError:“str”对象没有属性“current\u parameters”
,这在我看来是意料之中的…当我更新条目中的另一列时,这也会造成问题,并且没有提供参数
某些\u字符串
,就像通过在相关模型中添加关系间接更新字段一样。如何修复它?