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.