Как выполнить raw SQL в приложении SQLAlchemy-flask
Как вы выполняете raw SQL в SQLAlchemy?
У меня есть веб-приложение python, которое работает на flask и взаимодействует с базой данных через 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()
звонок. Элемент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()
документы: учебник по языку выражений SQL-использование текста
пример:
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> )
и привязать параметры, как описано в документах? Это может помочь решить многие проблемы форматирования параметров и производительности. Может быть, ошибка шлюза-это тайм-аут? Параметры привязки, как правило, делают сложные запросы выполняются значительно быстрее.