Mysql
 sql >> Database >  >> RDS >> Mysql

SQLAlchemy WHERE IN valore singolo (SQL grezzo)

No, i parametri SQL si occupano solo di scalare i valori. Dovrai generare l'SQL qui; se hai bisogno di SQL grezzo, usa:

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

per esempio. genera parametri sufficienti per contenere tutti i valori in some_list con la formattazione della stringa, quindi genera i parametri corrispondenti per riempirli.

Sarebbe ancora meglio usare un literal_column() oggetto per fare tutta la generazione per te:

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

ma allora potresti semplicemente generare l'intera istruzione usando il modulo `sqlalchemy.sql.expression, poiché ciò renderebbe molto più semplice il supporto di più dialetti di database.

Inoltre, il uid_in l'oggetto contiene già riferimenti ai valori corretti per i parametri di associazione; invece di trasformarla in una stringa come facciamo con str.format() azione sopra, SQLAlchemy avrebbe l'oggetto effettivo più i parametri associati e non dovresti più generare i params dizionario o .

Dovrebbe funzionare quanto segue:

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

dove sqlalchemy.sql.select() prende una specifica di colonna (qui codificata in * ), una clausola where (generata dalle due clausole con & per generare un AND SQL clausola) e un elenco di selezionabili; qui il tuo sqlalchemy.sql.table() valore.

Demo veloce:

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

ma l'albero degli oggetti effettivo generato da tutto ciò contiene anche i valori effettivi per i parametri di bind, quindi my_sess.execute() può accedervi direttamente.