Suponiendo que la variable de terms
contiene fragmentos de sentencias SQL válidos, puede simplemente pasar terms
precedido por un asterisco a or_
o and_
:
>>> from sqlalchemy.sql import and_, or_
>>> terms = ["name='spam'", "email='[email protected]'"]
>>> print or_(*terms)
name='spam' OR email='[email protected]'
>>> print and_(*terms)
name='spam' AND email='[email protected]'
Tenga en cuenta que esto supone que terms
incluye solamente válida y escapó correctamente fragmentos SQL, por lo que esto es potencialmente inseguro si un usuario malintencionado puede acceder terms
someh Ay.
En lugar de crear fragmentos de SQL usted mismo, debe dejar que SQLAlchemy cree consultas SQL parametrizadas utilizando otros métodos desde sqlalchemy.sql
. No sé si ha preparado objetos Table
para sus tablas o no; si es así, suponga que tiene una variable llamada users
que es una instancia de Table
y describe su tabla users
en la base de datos. A continuación, puede hacer lo siguiente:
from sqlalchemy.sql import select, or_, and_
terms = [users.c.name == 'spam', users.c.email == '[email protected]']
query = select([users], and_(*terms))
for row in conn.execute(query):
# do whatever you want here
Aquí, users.c.name == 'spam'
creará un objeto sqlalchemy.sql.expression._BinaryExpression
que registra que esta es una relación de igualdad binaria entre la columna de la tabla de name
users
y una cadena literal que contiene spam
. Cuando convierte este objeto en una cadena, obtendrá un fragmento de SQL como users.name = :1
, donde :1
es un marcador de posición para el parámetro. El objeto _BinaryExpression
también recuerda el enlace de :1
al 'spam'
, pero no lo insertará hasta que se ejecute la consulta SQL. Cuando se inserta, el motor de base de datos se asegurará de que se haya escapado correctamente. Lectura recomendada: SQLAlchemy's operator paradigm
Si sólo tiene la tabla de base de datos, pero usted no tiene una variable users
que describe la tabla, puede crear usted mismo:
from sqlalchemy import Table, MetaData, Column, String, Boolean
metadata = MetaData()
users = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String),
Column('email', String),
Column('active', Integer)
)
Como alternativa, puede utilizar la auto-carga que consulta el motor de base de datos para la estructura de la base de datos y compila users
automáticamente; Obviamente esto es más lento:
users = Table('users', metadata, autoload=True)
¿Alguna sugerencia sobre dónde buscar para descubrir cómo puedo crear "fragmentos SQL válidos y escapados correctamente" de una lista de cadenas? –
He buscado en la documentación de SQLAlchemy por un tiempo, pero parece que esta no es la forma correcta de hacerlo con SQLAlchemy. En lugar de crear fragmentos de SQL usted mismo, debe dejar que SQLAlchemy genere consultas SQL parametrizadas usando otros métodos de 'sqlalchemy.sql'. Extenderé mi respuesta en breve para proporcionar más detalles. –