it-swarm.com.de

Abfrage nach Attributliste anstelle von Tupeln in SQLAlchemy

Ich frage nach den IDs eines Modells und erhalte eine Liste von (int,)-Tupeln zurück anstatt einer Liste von IDs. Gibt es eine Möglichkeit, das Attribut direkt abzufragen?

result = session.query(MyModel.id).all()

Ich weiß, dass es möglich ist 

results = [r for (r,) in results]

Kann die Abfrage dieses Formular direkt zurücksenden, anstatt es selbst bearbeiten zu müssen?

9
PapeK24

Bei der Übergabe von ORM-instrumentierten Deskriptoren, wie z. B. einer Spalte, ist jedes Ergebnis ein mit dem Namen Tuple , selbst für nur eine Spalte. Sie können den Spaltennamen in einem Listenverständnis verwenden, um die Liste zu "reduzieren" (Sie können den Aufruf .all() löschen, die Iteration ruft auch die Objekte ab):

result = [r.id for r in session.query(MyModel.id)]

oder nutzen Sie die Tatsache, dass es sich um ein Tupel handelt, wenn Sie eine for-Schleife durchlaufen, und entpacken Sie sie in ein Tupel mit einem einzigen Element von Zielen:

result = session.query(MyModel.id)
for id, in result:
    # do something with the id

Letzteres könnte auch für ein Listenverständnis verwendet werden:

[id for id, in session.query(MyModel.id)]

Sie haben nicht wirklich die Möglichkeit, die Zeilenergebnisse als nur den einzelnen id-Wert zu erzwingen.

14
Martijn Pieters

Es ist merkwürdig, dass SQLalchemie keine richtige Lösung bietet. Wenn in sqlalchemy eine Membervariable wie eine Spalte ausgewählt wird, ist jedes Ergebnis ein benanntes Tuple, wie @Martijn sagte. Zu einer Lösung kam ich mit der Zip-Funktion von Python

offizielle Dokumentation der Zip

Zip (seq1 [ seq2 [...]]) -> [(seq1 [0], seq2 [0] ...), (...)] Gibt eine Liste von Tupeln zurück, bei denen jeder Tupel das i-te Element enthält von jeder der Argumentsequenzen. Die zurückgegebene Liste wird abgeschnitten in Länge auf die Länge der kürzesten Argumentsequenz.

Kommen Sie zu Ihrem Beispiel

result = session.query(MyModel.id).all()
result = Zip(*result)[0]

Ausgabe:

[id1, id2, id3...]

Wie es funktioniert, wird die Liste der als Argument angegebenen Tupel abgeflacht, wenn Sie die Liste wie übergeben 

[(key11, key21), (key12,key22)]

Zip konvertiert diese Liste von Tupeln in 

[(key11, key12), (key21, key22)]

In Ihrem Fall möchten Sie jeden Initialwert von tupe, der sich auf MyModel befindet, so dass Sie den 0. Tupel aus der Liste entnehmen können.

1
anand tripathi
q_stringlist = [q[0] for q in session.query((distinct(Table.column))).all()]                                                        

für Flask SQLAlchemy

q_stringlist = [q[0] for q in db.session.query((distinct(Table.column))).all()]   
0
Patrick