sql >> Base de Datos >  >> RDS >> Mysql

SQLAlchemy DONDE EN valor único (SQL sin procesar)

No, los parámetros de SQL solo tratan con escalar valores. Tendrás que generar el SQL aquí; si necesita SQL sin procesar, use:

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

p.ej. generar suficientes parámetros para contener todos los valores en some_list con formato de cadena, luego genere parámetros coincidentes para completarlos.

Mejor aún sería usar un literal_column() objeto para hacer toda la generación por ti:

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

pero entonces quizás podría generar la declaración completa usando el módulo `sqlalchemy.sql.expression, ya que esto facilitaría el soporte de múltiples dialectos de bases de datos.

Además, el uid_in el objeto ya contiene referencias a los valores correctos para los parámetros de vinculación; en lugar de convertirlo en una cadena como hacemos con str.format() acción anterior, SQLAlchemy tendría el objeto real más los parámetros asociados y ya no tendría que generar los params diccionario cualquiera .

Lo siguiente debería funcionar:

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

donde sqlalchemy.sql.select() toma una especificación de columna (aquí codificada de forma rígida a * ), una cláusula where (generada a partir de las dos cláusulas con & para generar un SQL AND cláusula) y una lista de seleccionables; aquí tu sqlalchemy.sql.table() valor.

Demostración rápida:

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

pero el árbol de objetos real generado a partir de todo esto también contiene los valores reales para los parámetros de vinculación, por lo que my_sess.execute() puede acceder a estos directamente.