Ich habe ein boolesches Feld in der MySQL-DB-Tabelle.
# table model
class TestCase(Base):
__tablename__ = 'test_cases'
...
obsoleted = Column('obsoleted', Boolean)
Um die Anzahl aller nicht veralteten Testfälle zu ermitteln, gehen Sie einfach wie folgt vor:
caseNum = session.query(TestCase).filter(TestCase.obsoleted == False).count()
print(caseNum)
Das funktioniert gut, aber der flake8 meldet die folgende Warnung:
E712: Der Vergleich mit False sollte "wenn cond False:" oder "if not cond:" sein.
Okay, ich denke das macht Sinn. Ändern Sie also meinen Code wie folgt:
caseNum = session.query(TestCase).filter(TestCase.obsoleted is False).count()
oder
caseNum = session.query(TestCase).filter(not TestCase.obsoleted).count()
Aber keiner von ihnen kann arbeiten. Das Ergebnis ist immer 0. Ich denke, die Filterklausel unterstützt den Operator "ist" oder "ist nicht" nicht. Kann mir jemand sagen, wie ich mit dieser Situation umgehen soll? Ich möchte die Flocke nicht deaktivieren.
python
mysql
sqlalchemy
flake8
Jruv
quelle
quelle
Antworten:
Das liegt daran, dass SQLAlchemy-Filter einer der wenigen Orte sind, an denen dies
== False
tatsächlich Sinn macht. Überall sonst sollten Sie es nicht verwenden.Fügen Sie
# noqa
der Zeile einen Kommentar hinzu und fertig.Oder Sie können verwenden
sqlalchemy.sql.expression.false
:from sqlalchemy.sql.expression import false TestCase.obsoleted == false()
Dabei wird
false()
der richtige Wert für Ihren Sitzungs-SQL-Dialekt zurückgegeben. Es gibt eine Übereinstimmungsqlalchemy.expression.true
.quelle
SQL Alchemy hat auch
is_
undisnot
Funktionen, die Sie verwenden können. Ein Beispiel wäreModel.filter(Model.deleted.is_(False))
Mehr dazu hier
quelle
is
und==
sind unterschiedlich, aber ich bin mir ziemlich sicher, dass das hier generierte SQL das gleiche sein wird.is
und==
unterscheiden sich in SQLAlchemy, da Sie den Identitätsoperator (is
) in Python nicht überschreiben können . Ein Ausdruck wieModel.column is False
wird immer so ausgewertet,False
dass der Vergleich immer sofort in Python und nicht in der Datenbank erfolgt. Das Ergebnis des Vergleichs der Identität eines Spaltenobjekts mit einem Booleschen Wert ist immerFalse
. Dadurch werden Anweisungen wieWHERE FALSE
oderAND FALSE
in Ihre Abfrage eingefügt, was in den meisten Fällen dazu führt, dass 0 Zeilen zurückgegeben werden, unabhängig davon, was passiert.Ich habe einen Blick darauf, welche genaue Abfrage generiert wird,
SQLAlchemy
wenn==
undis_
wann der DatenbankdialektPostgresql
für ein boolesches Feld verwendet wird:denn
==
wir bekommen:field == False
wird konvertiert zufield = false
field == True
wird konvertiert zufield = true
field == None
wird konvertiert zufield IS NULL
denn
is_()
wir bekommen:field.is_(False)
wird konvertiert zufield IS false
field.is_(True)
wird konvertiert zufield IS true
field.is_(None)
wird konvertiert zufield IS NULL
HINWEIS:
is_(not None)
Wird dahingehend bewertet,is_(bool(not None)
wasis_(True)
Geben gibt ,field = true
sodass Sie lieberisnot(None)
produzierenfield IS NOT NULL
quelle
is
anstelle von=
PostgreSQL niemals NULL als Antwort erhalten, selbst wenn ein Operand NULL ist.=
gibt NULL zurück, wenn einer der Operanden NULL ist.@Jruv
# noqa
Vor Anweisung verwenden, wird die Warnung ignoriert.quelle
# noqa
deaktiviert flake8 / pep / other-linters für den gesamten String, sodass auch andere Flusenwarnungen ignoriert werden. Andere Antworten bieten bessere Lösungen, zum Beispiel die.is_
Methode.