Mysql
 sql >> Base de données >  >> RDS >> Mysql

SQLAlchemy WHERE IN valeur unique (SQL brut)

Non, les paramètres SQL ne traitent que de scalaire valeurs. Vous devrez générer le SQL ici; si vous avez besoin de SQL brut, utilisez :

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()

par exemple. générer suffisamment de paramètres pour contenir toutes les valeurs dans some_list avec le formatage de chaîne, puis générez des paramètres correspondants pour les remplir.

Mieux encore serait d'utiliser un literal_column() objet pour faire toute la génération pour vous :

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()

mais alors vous pourriez peut-être simplement générer l'instruction entière en utilisant le module `sqlalchemy.sql.expression, car cela faciliterait la prise en charge de plusieurs dialectes de base de données.

De plus, le uid_in l'objet contient déjà des références aux bonnes valeurs pour les paramètres de liaison ; au lieu de le transformer en chaîne comme nous le faisons avec le str.format() action ci-dessus, SQLAlchemy aurait l'objet réel plus les paramètres associés et vous n'auriez plus à générer les params dictionnaire soit .

Ce qui suit devrait fonctionner :

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]))

où le sqlalchemy.sql.select() prend une spécification de colonne (ici codée en dur en * ), une clause where (générée à partir des deux clauses avec & pour générer un AND SQL clause) et une liste de sélectionnables ; ici votre un sqlalchemy.sql.table() valeur.

Démo rapide :

>>> 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)

mais l'arborescence d'objets réelle générée à partir de tout cela contient également les valeurs réelles des paramètres de liaison, donc my_sess.execute() peuvent y accéder directement.