python - engine - sqlalchemy raw sql
Cómo ejecutar SQL sin formato en la aplicación SQLAlchemy-flask (6)
¿Ha intentado usar connection.execute(text( <sql here> ), <bind params here> )
y enlazar parámetros como se describe en los documentos ? Esto puede ayudar a resolver muchos problemas de formato y rendimiento de los parámetros. Tal vez el error de la puerta de enlace es un tiempo de espera? Los parámetros de enlace tienden a hacer que las consultas complejas se ejecuten de forma sustancialmente más rápida.
¿Cómo se ejecuta SQL sin procesar en SQLAlchemy?
Tengo una aplicación web de Python que se ejecuta en un matraz e interfaces a la base de datos a través de SQLAlchemy.
Necesito una forma de ejecutar el SQL sin procesar. La consulta implica varias combinaciones de tabla junto con vistas en línea.
He intentado:
connection = db.session.connection()
connection.execute( <sql here> )
Pero sigo recibiendo errores de puerta de enlace.
Has probado:
result = db.engine.execute("<sql here>")
o:
from sqlalchemy import text
sql = text(''select name from penguins'')
result = db.engine.execute(sql)
names = []
for row in result:
names.append(row[0])
print names
Puede obtener los resultados de SELECT SQL queries usando from_statement()
y text()
como se muestra here . No tienes que lidiar con tupules de esta manera. Como ejemplo para un usuario de clase que tenga el nombre de tabla ''usuarios'', puede intentarlo,
from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
text("SELECT * FROM users where name=:name"))./
params(name=''ed'').all()
return user
Si desea utilizar una sesión (como lo sugiere su pregunta), use su método de execute
directamente:
import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session
engine = sqlalchemy.create_engine(''my connection string'')
Session = scoped_session(sessionmaker(bind=engine))
s = Session()
result = s.execute(''SELECT * FROM my_table WHERE my_column = :val'', {''val'': 5})
Lo siguiente puede ser específico para mi controlador de base de datos (psycopg2); No estoy seguro. De todos modos, así es como saco mis valores.
from collections import namedtuple
Record = namedtuple(''Record'', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
print(r)
El punto clave es la llamada fetchall()
. La parte namedtuple
es algo que encuentro que me hace la vida más fácil al dar acceso basado en el nombre.
Además, esto es transaccional sin administrarlo manualmente. Say make_session
es una función que crea una sesión:
>>> s1 = make_session()
>>> s1.execute(''CREATE TABLE blah (id INTEGER)'')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD86F0>
>>> s1.commit()
>>>
>>> s1.execute(''INSERT INTO blah VALUES (1)'')
<sqlalchemy.engine.result.ResultProxy object at 0x02CD8870>
>>> s1.execute(''SELECT * FROM blah'').fetchall()
[(1,)]
>>>
>>> s2 = make_session()
>>> s2.execute(''SELECT * FROM blah'').fetchall()
[]
>>> s2.close()
>>>
>>> s1.commit()
>>>
>>> s2 = make_session()
>>> s2.execute(''SELECT * FROM blah'').fetchall()
[(1,)]
>>> s2.close()
>>> s1.close()
docs: Tutorial del lenguaje de expresiones SQL - Uso del texto
ejemplo:
from sqlalchemy.sql import text
connection = engine.connect()
# recommended
cmd = ''select * from Employees where EmployeeGroup == :group''
employeeGroup = ''Staff''
employees = connection.execute(text(cmd), group = employeeGroup)
# or - wee more difficult to interpret the command
employeeGroup = ''Staff''
employees = connection.execute(
text(''select * from Employees where EmployeeGroup == :group''),
group = employeeGroup)
# or - notice the requirement to quote "Staff"
employees = connection.execute(
text(''select * from Employees where EmployeeGroup == "Staff"''))
for employee in employees: logger.debug(employee)
# output
(0, u''Tim'', u''Gurra'', u''Staff'', u''991-509-9284'')
(1, u''Jim'', u''Carey'', u''Staff'', u''832-252-1910'')
(2, u''Lee'', u''Asher'', u''Staff'', u''897-747-1564'')
(3, u''Ben'', u''Hayes'', u''Staff'', u''584-255-2631'')
result = db.engine.execute(text("<sql here>"))
ejecuta el <sql here>
pero no lo confirma a menos que esté en el modo de confirmación autocommit
. Por lo tanto, las inserciones y actualizaciones no se reflejarían en la base de datos.
Para comprometerse después de los cambios, haga
result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))