2010-07-24 10 views
42

Ich verwende das MySQLicious-Typ-Schema here für ein einfaches Tagging-System beschrieben. Ich habe einige alternative Implementierungen des Tagging-Schemas in 4 verschiedenen SO-Threads gelesen, und das passt am besten zu meinen Bedürfnissen.Elixir/SQLAlchemy entspricht SQL "LIKE" Anweisung?

Eine Sammlung von Einträgen haben die Tags „banane orange“ und „Erdbeer-Banane Zitrone“, und ich versuche, die Elixier/SQLAlchemy äquivalente Aussage

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

Ich habe zu finden nicht in der Lage um einen solchen Weg zu finden, einen Class.query.filter/filter_by() Befehl zu strukturieren, und kann keine ähnliche Methode in der Dokumentation für jedes Modul sehen. Gibt es einen einfachen Weg, dies zu tun? Oder sollte ich nur Raw SQL verwenden.

Extra Frage: Ein Nachteil des MySQLicious-Schemas ist der Fall, in dem ich nach "% apple%" suchen, aber "ananas" zurückgegeben haben möchte. Gibt es einen High-Level-Weg, um mit diesem Testfall umzugehen? Oder sollte ich nur ein führendes Leerzeichen in jede Abfrage einfügen?

n.B: Für diejenigen, die sich interessieren, ist dies meine erste Erfahrung mit Datenbanken, so kann ich die Kernvorteile des in anderen Threads erwähnten Schemas übersehen. Meine Anwendung ist für das Protokollieren eines Satzes oder zwei über eine abgeschlossene Aufgabe mit Spalten [TaskID, Tags, Notizen, StartTime, StopTime, TimeTaken], ein bisschen wie ein einfaches Journal. Meistens für Tutorialzwecke. Ich möchte in der Lage sein, nach einzelnen Tags zu suchen, um herauszufinden, wie viel Zeit ich für eine bestimmte Aufgabe aufwenden kann.

+0

Die „hier“ Tag führt zu einem 404 :( – David

Antwort

75

Jede Spalte hat. Like-Methode, die als Filterklausel verwendet werden kann.

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

Perfect! Wissen Sie, ob es eine bessere Art und Weise zwischen Apfel zu unterscheiden und Ananas als ein führendes Leerzeichen hinzufügen? –

+2

Der beste Weg wäre, nur Ihre Datenbank zu normalisieren und 2 separate Tabellen für Tags und Tag-to-Task-Beziehungen hinzuzufügen, und dann JOIN statt LIKE zu verwenden.Andernfalls, ja, scheint wie Sie müssen haben Sie eine Art Trennzeichen um jedes Tag in der Zeichenkette. Leading Space ist nicht enou gh, da gibt es auch Stift und Stift, mit% Stift%. Wenn Sie etwas wie "| Apfel | Ananas | Stift | Bleistift |" und passen Sie "% | pen |%" an, es sollte nicht kollidieren. –

+1

Bei der Normalisierung bin ich mir nicht ganz sicher, wie ich mehr als ein Tag mit einer bestimmten Aufgabe verbinden kann oder umgekehrt, mit der Tag-Map. Die "Toxi" -Lösung scheint die Sammlung von Tags als einzelnes Element zu gruppieren, anstatt sie einzeln zu speichern. Und die Methode, die in diesem (http://elixir.ematia.de/trac/wiki/Recipes/TagCloud) Rezept verwendet wird, scheint nur ein Tag pro Element zuzulassen. Welche Ressourcen wären am besten geeignet, um dieses Thema aufzuklären? Ich habe das auch gelesen (http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html), kann mir aber nicht vorstellen, wie man mehrere Tags verwaltet. –

4

Hinzufügen zu der obigen Antwort, wer nach einer Lösung sucht, können Sie auch versuchen, "Match" Operator anstelle von "wie". Ich möchte nicht voreingenommen sein, aber es funktionierte perfekt für mich in Postgresql.

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

Es erbt Datenbankfunktionen wie ENTHÄLT und MATCH. Es ist jedoch nicht in SQLite verfügbar.

Für weitere Informationen gehen Common Filter Operators

+0

Was ist der Unterschied zwischen diesen beiden Betreibern? – buhtz

2

diesen Code versuchen

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