2010-07-24 2 views
42

간단한 태깅 시스템에 대해 here으로 묘사 된 MySQLicious 형식 스키마를 사용하고 있습니다. 4 개의 다른 SO 스레드에서 태그 지정 스키마의 대체 구현을 읽었으며 이것이 내 요구 사항에 가장 잘 맞습니다.Elixir/SQLAlchemy는 SQL "LIKE"문과 동일합니까?

항목의 집합 태그 "사과 바나나 오렌지"와 "딸기 바나나 레몬"가, 그리고 내가 할 수 없었던

SELECT * FROM table WHERE tags LIKE "%banana%"; 

로 비약/SQLAlchemy의 동등한 문을 찾기 위해 노력하고있어 그런 식으로 Class.query.filter/filter_by() 명령을 구성 할 수있는 방법을 찾고, 어느 모듈에 대해서도 문서에서 비슷한 방법을 볼 수 없습니다. 이 작업을 수행하는 간단한 방법이 있습니까? 아니면 그냥 원시 SQL을 사용해야합니까?

추가 질문 :MySQLicious 스키마의 단점은 "% apple %"을 (를) 검색하고 "파인애플"을 반환하려는 경우입니다. 이 테스트 케이스를 처리 할 수있는 높은 수준의 방법이 있습니까? 아니면 각 쿼리에 선행 공백을 포함해야합니까?

n.B : 관심있는 사람들에게 이것은 데이터베이스에 대한 나의 첫 경험이므로 다른 스레드에서 언급 한 스키마의 핵심 이점을 간과 할 수 있습니다. 내 응용 프로그램은 간단한 저널과 같은 비트 [TaskID, 태그, 메모, StartTime, StopTime, TimeTaken], 완료된 작업에 대한 문장 또는 두 기록하는 것입니다. 대부분 자습서 목적입니다. 개별 태그로 검색하여 주어진 작업에 대략 얼마나 많은 시간을 소비 할 수 있는지 알고 싶습니다.

+0

을 시도 가서 "여기"태그 404 :( – David

답변

75

각 열에는 필터 절로 사용할 수있는 .like 메서드가 있습니다.

>>> Note.query.filter(Note.message.like("%somestr%")).all() 
[] 
+1

완벽한 리드! 당신이 사과를 구별 할 수있는 더 좋은 방법이 있는지 알고 계십니까 및 파인애플보다 선행 공간을 추가 하시겠습니까? –

+2

가장 좋은 방법은 데이터베이스를 표준화하고 태그와 태그 - 태스크 관계에 대해 2 개의 개별 테이블을 추가 한 다음 LIKE 대신 JOIN을 사용하는 것입니다. 그렇지 않으면 네가해야 할 것처럼 보인다. 문자열의 각 태그 주위에 구분 기호가 있어야합니다. 선행 공간은 enou가 아닙니다. 펜과 연필도 % pen % 사용하고 있습니다. "사과 | 파인애플 | 펜 | 연필 |" 충돌하지 않아야하는 "% | pen | %"와 일치해야합니다. –

+1

정규화를 사용하면 주어진 작업과 연관된 태그가 두 개 이상일 것입니다. 태그 맵을 사용하면 그 반대의 경우도 마찬가지입니다. "독시 (Toxi)"솔루션은 개별적으로 개별적으로 저장하는 대신 태그 모음을 단일 항목으로 그룹화하는 것으로 나타났습니다. 그리고이 (http://elixir.ematia.de/trac/wiki/Recipes/TagCloud) 레시피에 사용 된 방법은 항목 당 하나의 태그 만 허용하는 것으로 보입니다. 이 주제를 명확히하기 위해 어떤 자원이 가장 좋을까요? 나는 이것 (http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html)을 읽었지만 여러 태그를 관리하는 방법을 알 수 없다. –

4

위의 답에 덧붙여 해결책을 찾는 사람은 누구나 '좋아요'대신 '일치'연산자를 사용할 수도 있습니다. 편향되고 싶지는 않지만 Postgresql에서 완벽하게 작동했습니다.

Note.query.filter(Note.message.match("%somestr%")).all() 

MATCH을 CONTAINS와 같은 그것은 데이터베이스 기능을 상속합니다. 그러나 SQLite에서는 사용할 수 없습니다.

더 많은 정보 Common Filter Operators

+0

두 연산자의 차이점은 무엇입니까? – buhtz

2

이 코드

output = dbsession.query(<model_class>).filter(<model_calss>.email.ilike('%' + <email> + '%'))