2013-08-25 2 views
3

내 사용자가 데이터를 "카페"또는 "카페"로 저장할 수 있다는 점을 감안할 때 액센트를 구분하지 않는 쿼리로 해당 필드를 검색 할 수 있어야합니다.SQLALCHEMY 쿼리의 악센트를 무시하십시오.

나는 https://github.com/djcoin/django-unaccent/을 찾았지만 sqlalchemy에서 비슷한 것을 구현할 수 있는지는 잘 모른다.

저는 PostgreSQL을 사용하고 있습니다. 솔루션이이 데이터베이스에만 해당되는 경우 나에게 좋습니다. 그것이 일반적인 해결책이라면 훨씬 더 좋습니다.

도움 주셔서 감사합니다.

답변

5

먼저 PostgreSQL의에서 unaccess 확장 설치 :

from sqlalchemy.sql.functions import ReturnTypeFromArgs 

class unaccent(ReturnTypeFromArgs): 
    pass 

과 같이 사용 : create extension unaccent;

다음, 파이썬에서 SQL 기능 unaccent를 선언하면 확인

for place in session.query(Place).filter(unaccent(Place.name) == "cafe").all(): 
    print place.name 

큰 테이블을 가지고 있다면 올바른 인덱스를 가져야합니다. 그렇지 않으면 전체 테이블 스캔이됩니다.

+1

효과가있었습니다! 아래에 Miguel이 제안한 검색 문자열에서 유니 코드를 사용해야했습니다. 그것은'session.query (Place) .filter ((unaccent (Place.name) .ilike (string)))'와 같은 것을 알게되었습니다. 또한 대소 문자를 무시합니다. 고마워요! – guinunez

3

간단하고 데이터베이스에 독립적 인 솔루션은 악센트가있는 필드를 두 번, 악센트가없는 한 번, 한 번만 쓸 수 있도록 작성하는 것입니다. 그런 다음 액센트가없는 버전에 대한 검색을 수행 할 수 있습니다.

문자열의 액센트없는 vesherion을 생성하려면 Unidecode을 사용할 수 있습니다.

레코드가 삽입되거나 업데이트 될 때 데이터베이스에 액센트없는 버전을 자동으로 지정하려면 Column 정의에 defaultonupdate 절을 사용할 수 있습니다. 즉, 검색이 이루어집니다되는 일이기 때문에, 나는 단지 악센트가없는 필드 색인 방법

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) 

참고 : 예를 들어, 플라스크-SQLAlchemy의를 사용하여 당신이 뭔가를 할 수 있습니다.

물론 검색하기 전에 검색하려는 값을 unaccent로 가져와야합니다. 예를 들어 : 필요한 경우

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

당신은 전체 텍스트 검색에 동일한 기술을 적용 할 수 있습니다.

+0

고마워요! 마침내 user2716201의 접근 방식을 사용하는 동안 입력 문자열에 'unidecode'제안을 사용했습니다. 미안 해요, 당신의 대답을 upvote 수 없습니다, 분명히 나는 ​​현재 충분한 명성을 가지고 있지 않습니다. – guinunez

관련 문제