Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

SQLAlchemy WHERE IN valor único (SQL bruto)


Não, os parâmetros SQL só lidam com escalar valores. Você terá que gerar o SQL aqui; se você precisar de SQL bruto, 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()

por exemplo. gerar parâmetros suficientes para armazenar todos os valores em some_list com formatação de string e, em seguida, gere parâmetros correspondentes para preenchê-los.

Melhor ainda seria usar um literal_column() objeto para fazer toda a geração para você:
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()

mas então você poderia apenas gerar a declaração inteira usando o módulo `sqlalchemy.sql.expression, pois isso tornaria o suporte a vários dialetos de banco de dados muito mais fácil.

Além disso, o uid_in objeto já contém referências aos valores corretos para os parâmetros de ligação; em vez de transformá-lo em uma string como fazemos com o str.format() ação acima, SQLAlchemy teria o objeto real mais os parâmetros associados e você não precisaria mais gerar os params dicionário ou .

O seguinte deve 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]))

onde o sqlalchemy.sql.select() recebe uma especificação de coluna (aqui codificada para * ), uma cláusula where (gerada a partir das duas cláusulas com & para gerar um SQL AND cláusula) e uma lista de selecionáveis; aqui está o seu sqlalchemy.sql.table() valor.

Demonstração 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)

mas a árvore de objetos real gerada de tudo isso também contém os valores reais para os parâmetros de ligação, então my_sess.execute() pode acessá-los diretamente.