Как выполнить raw SQL в приложении SQLAlchemy-flask
Как вы выполняете raw SQL в SQLAlchemy?
У меня есть веб-приложение python, которое работает на колбе и интерфейсах к базе данных через SQLAlchemy.
Мне нужен способ запуска необработанного SQL. Запрос включает несколько соединений таблиц вместе со встроенными представлениями.
Я пробовал:
connection = db.session.connection()
connection.execute( <sql here> )
но я продолжаю получать ошибки шлюз.
6 ответов
вы пробовали:
result = db.engine.execute("<sql here>")
или:
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
если вы хотите использовать сессии (как ваш вопрос), используйте его execute
способ напрямую:
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})
следующее Может быть специфичным для моего драйвера базы данных (psycopg2); я не уверен. В любом случае, это то, как я вытаскиваю свои ценности.
from collections import namedtuple
Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
print(r)
ключевым моментом является fetchall()
звонок. The namedtuple
часть-это просто то, что я нахожу, упрощает мою жизнь, предоставляя доступ на основе имен.
кроме того, это транзакционные без управление вручную. Скажи make_session
- это функция, которая создает сеанс:
>>> 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:SQL Expression Language Tutorial-использование текста
пример:
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')
вы можете получить результаты выбора SQL-запросов с помощью from_statement()
и text()
как показано здесь. Ты не должен так обращаться с тупулсом. В качестве примера для пользователя класса, имеющего табличное имя "пользователи", Вы можете попробовать,
from sqlalchemy.sql import text
.
.
.
user = session.query(User).from_statement(
text("SELECT * FROM users where name=:name")).\
params(name='ed').all()
return user
result = db.engine.execute(text("<sql here>"))
выполняет <sql here>
но не совершает его, если вы не на autocommit
режим. Таким образом, вставки и обновления не будут отражаться в базе данных.
чтобы совершить после изменений, сделайте
result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
вы пробовали использовать connection.execute(text( <sql here> ), <bind params here> )
и параметры привязки, как описано в документах? Это может помочь решить многие проблемы форматирования параметров и производительности. Может быть, ошибка шлюза-это тайм-аут? Параметры привязки, как правило, заставляют сложные запросы выполняться значительно быстрее.