Mysql
 sql >> Datenbank >  >> RDS >> Mysql

SQLAlchemy WHERE IN Einzelwert (Roh-SQL)

Nein, SQL-Parameter behandeln immer nur skalare Werte. Sie müssen das SQL hier generieren; Wenn Sie rohes SQL benötigen, verwenden Sie:

statement = "SELECT * FROM table WHERE `key`='rating' AND uid IN ({})".format(
    ', '.join([':i{}'.format(i) for i in range(len(some_list))]))

my_sess.execute(
        statement, 
        params={'i{}'.format(i): v for i, v in enumerate(some_list)})
    ).fetchall()

z.B. Genügend Parameter generieren, um alle Werte in some_list aufzunehmen mit Zeichenfolgenformatierung, und generieren Sie dann übereinstimmende Parameter, um sie zu füllen.

Noch besser wäre es, einen <-Code zu verwenden>literal_column() Objekt um das Generieren für Sie zu erledigen:

from sqlalchemy.sql import literal_column

uid_in = literal_column('uid').in_(some_list)
statement = "SELECT * FROM able WHERE `key`='rating' AND {}".format(uid_in)

my_sess.execute(
        statement, 
        params={'uid_{}'.format(i): v for i, v in enumerate(some_list)})
    ).fetchall()

aber dann könnten Sie vielleicht einfach die ganze Anweisung mit dem Modul `sqlalchemy.sql.expression generieren, da dies die Unterstützung mehrerer Datenbankdialekte viel einfacher machen würde.

Außerdem ist die uid_in Objekt enthält bereits Verweise auf die richtigen Werte für die Bindungsparameter; anstatt es in einen String umzuwandeln, wie wir es mit str.format() tun Aktion oben hätte SQLAlchemy das eigentliche Objekt plus die zugehörigen Parameter und Sie müssten die params nicht mehr generieren Wörterbuch entweder .

Folgendes sollte funktionieren:

from sqlalchemy.sql import table, literal_column, select

tbl = table('table')
key_clause = literal_column('key') == 'rating'
uid_clause = literal_column('uid').in_(some_list)
my_sess.execute(select('*', key_clause & uid_clause, [tbl]))

wo die sqlalchemy.sql. select() nimmt eine Spaltenspezifikation (hier fest codiert zu * ), eine where-Klausel (erzeugt aus den beiden Klauseln mit & um ein SQL AND zu generieren Klausel) und eine Liste von auswählbaren Elementen; hier Ihre sqlalchemy.sql .table() Wert.

Schnelle Demo:

>>> from sqlalchemy.sql import table, literal_column, select
>>> some_list = ['foo', 'bar']
>>> tbl = table('table')
>>> key_clause = literal_column('key') == 'rating'
>>> uid_clause = literal_column('uid').in_(some_list)
>>> print select('*', key_clause & uid_clause, [tbl])
SELECT * 
FROM "table" 
WHERE key = :key_1 AND uid IN (:uid_1, :uid_2)

aber der eigentliche Objektbaum, der aus all dem generiert wird, enthält auch die eigentlichen Werte für die Bindungsparameter, also my_sess.execute() direkt darauf zugreifen können.