SqlAlchemy query generator

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Moin,

ich hätte da mal ne Frage ob man das umsetzen könnte, bzw. ob das überhaupt Sinn macht.

Und zwar habe eine Stelle wo ich mir ein query bauen muss allerdings nicht genau weiß wie viele Variablen es gibt, also von 1-7 wäre da alles möglich.

Also quasi ein
__table__.query.filter(__table__.column1 == 'element').all()
oder je nachdem z.B. auch
__table__.query.filter(and_(__table__.column1 == ''element', __table__.column2 == 'element2', __table__.column3 == 'element3').all()

Die Columns haben eine Feste Reihenfolge in der sie dazu kommen würden, ich weiß nur halt nicht wie viele es werden bevor die Anfrage vom Client kommt.

Alternativ könnte ich auch für jede Variante was bauen und das mit If abklappern aber das wäre ... unschön.
Daher die Frage ob es da vielleicht ne bessere Möglichkeit gibt.
BlackJack

@taake: Wie wäre es mit einer Schleife? Dir ist klar das die meisten Methoden auf `Query`-Objekten ein neues `Query`-Objekt liefern eben um die enstprechende Information erweitert!? Darauf kann man dann wieder eine Methode aufrufen die ein `Query`-Objekt liefert das erneut um etwas erweitert wurde.

Code: Alles auswählen

    query_data = [
        (__table__.column1, 'element1'), (__table__.column2, 'element2'), # ...
    ]
    query = __table__.query()
    for column, value in query_data:
        query = query.filter(column == value)
    result = query.all()
Das ist ja gerade eine der sehr schönen Eigenschaften von SQLAlchemy, dass man Abfragen Stück für Stück aufbauen kann, und zwar ohne dass man SQL als Zeichenketten zusammenfrickeln muss.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

Danke für die schnelle Antwort :D
Und jetzt wo du es sagst wird es mir klarer, allerdings
komm ich nicht wirklich klar mit deinem Beispiel.
Scheinbar hab ich doch noch irgendwie ein Verständnisproblem :(

Code: Alles auswählen

def catsplit(folder):
   PathElements = folder.split('/')
   query_data = [(Info.cat_lvl0, 'elem'), (Info.cat_lvl1, 'elem'), (Info.cat_lvl2, 'elem'), \
                       (Info.cat_lvl3, 'elem'), (Info.cat_lvl4, 'elem'), \
                       (Info.cat_lvl5, 'elem'), (Info.cat_lvl6, 'elem')]
   query = Info.query()
   for value in PathElements:
      for column, value in query_data:
         query = query.filter(column == value)
   result = query.all()
   print result

catsplit('foo/bar/foobar')
Hab ich das so richtig verstanden?
Weil leider bekomme ich immer ein

query = Info.query()
TypeError: 'BaseQuery' object is not callable

Muss leider auch gestehen das SqlAlchemy immer noch was von nem Balrog hat der sich einem in den Weg stellt.
BlackJack

@taake: Die Meldung ist doch eindeutig — im Gegensatz zu Deinen Code habe ich versucht das `query`-Attribut aufzurufen, was halt falsch ist.

Deine Schleifen sehen komisch aus weil Du das `value` aus der äusseren Schleife nirgends verwendest, dafür das `value` in der inneren Schleife aber immer den gleichen Wert hat. Ich denke mal das sollte eher so aussehen (ungetestet):

Code: Alles auswählen

def category_split(folder):
    query = Info.query
    for i, value in enumerate(folder.split('/')):
        query = query.filter(getattr(Info, 'cat_lvl{0}'.format(i)) == value)
    print query.all()
Die durchnummerierten Spaltennamen sind auch ein „code smell”.
taake
User
Beiträge: 125
Registriert: Donnerstag 14. Oktober 2010, 08:49

@BlackJack: Vielen Dank!

Das ist mehr als ich erhofft hatte, enumerate kannte ich gar nicht.
Funktioniert genau so wie erhofft.


you made my day ;)
Antworten