Jak wysłać zapytanie do bazy danych według identyfikatora za pomocą SqlAlchemy?


98

Muszę wysłać zapytanie do bazy danych SQLAlchemy na podstawie idczegoś podobnego do

User.query.filter_by (nazwa użytkownika = 'peter')

ale dla id. Jak mam to zrobic? [Wyszukiwanie w Google i SO nie pomogło]


Podaj więcej szczegółów, na przykład równoważny kod SQL lub pseudokod, który robi, co chcesz. Co to jest „identyfikator bazy danych SQLAlchemy”?
Daniel Kluev,

Czy Twoja tabela ma kolumnę id?
Keith,

Odpowiedzi:


135

Query ma funkcję get, która obsługuje zapytania przy użyciu klucza podstawowego tabeli, co, jak zakładam, idjest.

Na przykład, aby zapytać o obiekt o identyfikatorze 23:

User.query.get(23)

Uwaga: jak wspomniało kilku innych komentatorów i odpowiedzi, nie jest to po prostu skrót od „Przeprowadź filtrowanie zapytań na kluczu podstawowym”. W zależności od stanu sesji SQLAlchemy, uruchomienie tego kodu może spowodować wysłanie zapytania do bazy danych i zwrócenie nowej instancji lub może zwrócić wystąpienie obiektu odpytanego wcześniej w kodzie bez faktycznego wysyłania zapytania do bazy danych. Jeśli jeszcze tego nie zrobiłeś, rozważ przeczytanie dokumentacji dotyczącej sesji SQLAlchemy, aby zrozumieć konsekwencje.


9
Funkcja get wspiera także wiele kluczy głównych: YourModel.query.get((pk1, pk2)). Zwróć uwagę na krotkę.
marc_aragones

3
Do get()zapytań funkcyjnych obiektów przez klucz podstawowy. Jeśli chcesz przesyłać zapytania według id, najpierw ustaw idjako klucz podstawowy.


7

get () czasami nie jest zgodne z oczekiwaniami:

jeśli transakcja została wykonana:

>>> session.query(User).get(1)
[SQL]: BEGIN (implicit)
[SQL]: SELECT user.id AS user_id, user.name AS user_name, user.fullname AS user_fullname
FROM user
WHERE user.id = ?
[SQL]: (1,)
<User(u'ed', u'Ed Jones')>

jeśli jesteś w transakcji (get () da ci wynik w pamięci bez zapytania do bazy danych):

>>> session.query(User).get(1)
<User(u'ed', u'Ed Jones')>

lepiej tego użyć:

>>> session.query(User.name).filter(User.id == 1).first()
[SQL]: SELECT user.name AS user_name
FROM user
WHERE user.id = ?
 LIMIT ? OFFSET ?
[SQL]: (1, 1, 0)
(u'Edwardo',)

1
Jak to zachowanie jest nieoczekiwane?
Solomon Ucko

Chodzi mi o to, że jeśli w transakcji (nie sesja. Jeszcze wysłałeś) get()wydaje się, że daje ci obiekt wyniku w pamięci (bez faktycznego odpytywania bazy danych), ale filter().first()zawsze będzie odpytywać bazę danych.
panda912

Czy można jednocześnie zmienić bazę danych podczas transakcji? Jeśli nie, użycie getjest lepsze ze względu na wzrost wydajności.
Solomon Ucko

1
jak wiem, sqlalchemy nie może pracować z elementami asynchronicznymi (wydaje się tylko z geventem) i tak, getjest bardziej wydajne.
panda912

Dlaczego .first () różni się od .get (), jeśli chodzi o transakcję? Czy .first () zawsze wraca do bazy danych? Czy to jest tak, że .get () najpierw szuka w bieżącym pliku env, aby sprawdzić, czy zna ten identyfikator czy coś takiego?
msouth

1

Jeśli używasz, tables reflectionmożesz mieć problemy z podanymi rozwiązaniami. (Poprzednie rozwiązania tutaj nie działały dla mnie).

Skończyło się na tym, że użyłem:

session.query(object._class_).get(id)

( objectzostał pobrany przez odbicie z bazy danych, dlatego musisz użyć .__class__)

Mam nadzieję, że to pomoże.


0

Najpierw należy ustawić idjako klucz podstawowy.
Następnie możesz użyć tej query.get()metody do odpytywania obiektów, idktóre są już kluczem podstawowym.

Ponieważ query.get()metoda zapytań o obiekty za pomocą klucza podstawowego.
Wyprowadzono z dokumentacji Flask-SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy()
db.init_app(app)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)

def test():
    id = 1
    user = User.query.get(id)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.