2015-10-04 5 views
10

Ich habe eine Flask-Anwendung, die Flask-SQLAlchemy verwendet, um eine Verbindung zu einer MySQL-Datenbank herzustellen.Flask-SQLAlchemy überprüfen, ob Zeile in Tabelle

Ich möchte in der Lage sein zu überprüfen, ob eine Zeile in einer Tabelle vorhanden ist. Wie würde ich eine Abfrage wie ändern, um die Zeile zu überprüfen vorhanden:

db.session.query(User).filter_by(name='John Smith') 

ich eine Lösung auf this question gefunden, die SQLAlchemy verwendet, aber scheint nicht mit der Art und Weise Flask-SQLAlchemy arbeitet zu passen:

from sqlalchemy.sql import exists  
print session.query(exists().where(User.email == '...')).scalar() 

Danke.

+0

In welcher Weise die erste Abfrage * nicht * prüfen, ob die Zeile vorhanden? –

+0

Ich möchte, dass die Abfrage "True" oder "False" zurückgibt, wenn die Zeile existiert. –

+0

Was ist los mit der zweiten Methode? Es funktioniert gut in Flask-SQLAlchemy, ich habe es gerade versucht. – davidism

Antwort

16

Da Sie nur sehen möchten, ob der Benutzer existiert, wollen Sie nicht das gesamte Objekt abfragen. Einfach die ID abfragen, sie existiert, wenn die skalare Rückgabe nicht None ist.

exists = db.session.query(User.id).filter_by(name='davidism').scalar() is not None 

Die zweite Abfrage, die Sie auch in Ordnung zeigte arbeitet, Flask-SQLAlchemy tut nichts, jede Art von Abfrage zu verhindern, die SQLAlchemy machen kann.

exists = db.session.query(db.exists().where(User.name == 'davidism')).scalar() 
8

Wrap eine .exists() Abfrage in einer anderen session.query() mit einem scalar() Anruf am Ende.

exists = db.session.query(
    db.session.query(User).filter_by(name='John Smith').exists() 
).scalar() 
+0

Sie sollten wirklich 'User.id' abfragen, sonst machen Sie SQLAlchemy generieren eine viel größere Abfrage, als es erforderlich ist. Dies ist auch das gleiche wie in meinem zweiten Beispiel, ich benutze nur 'query.exists' anstelle von' db.exists', was im Wesentlichen das Gleiche ist. – davidism

+0

@davidism SQLAlchemy übersetzt dies in 'SELECT EXISTS (SELECT 1 FROM Benutzer WHERE user.name =?)'. Dies ist eine geringfügig längere Abfrage als SELECT user.id FROM Benutzer WHERE user.name = ?, aber es spiegelt genauer die eigentliche Frage, die gestellt wird. Auf der Python-Seite sieht der Code ähnlich aus wie beim Abrufen eines Benutzers, wodurch die Abfrage leicht zu merken und zu verstehen ist. – lyschoening

+0

Die beiden existieren unterschiedliche Abfragen? Interessant, ich muss überprüfen, habe eine solche Anfrage schon lange nicht mehr gemacht. – davidism

0

die Entführung Vergib aber ... mit den hier gegebenen Anweisungen habe ich die folgende WTForm Validator Einzigartigkeit des Feldes

class Unique(object): 
    def __init__(self, column, session, message="Already exists."): 
     self.column = column 
     self.session = session 
     self.message = message 

    def __call__(self, form, field): 
     if field.data == field.object_data: 
      return # Field value equals to existing value. That's ok. 
     model = self.column.class_ 
     query = model.query.filter(self.column == field.data).exists() 
     if self.session.query(query).scalar(): 
      raise ValidationError(self.message) 

es so

class Register(Form): 
    email = EmailField('Email', [Unique(User.email, db.session)]) 
verwendet würde, um zu prüfen

Allerdings würde ich gerne API haben, die db-session als zweiten param nicht benötigt

class Register(Form): 
    email = EmailField('Email', [Unique(User.email)]) 

Gibt es eine Möglichkeit, Db-Sitzung vom Modell zu erhalten? Ohne Sitzung scheint es unmöglich zu sein, zu vermeiden, dass das gesamte Objekt geladen wird, um seine Existenz zu überprüfen.

-2

Denken Sie es ist ein Tippfehler in der Antwort des davidism, das funktioniert für mich:

exists = db.session.query(**User**).filter_by(name='davidism').scalar() is not None 
+0

Es ist kein Tippfehler, ich frage speziell die ID, weil das Holen des gesamten Objekts für das Überprüfen der Existenz übertrieben ist. – davidism