Как я могу выполнить весь sql файл в базе данных с помощью SQLAlchemy? В файле может быть много разных sql-запросов, включая begin и commit/rollback.
Выполнить SQL из файла в SQLAlchemy
Ответ 1
К сожалению, я не знаю хорошего общего ответа для этого. Некоторые dbapi (например, psycopg2) поддерживают выполнение множества операторов за раз. Если файлы не огромны, вы можете просто загрузить их в строку и выполнить их при соединении. Для других я попытался использовать клиент командной строки для этого db и передать данные в это с помощью модуля подпроцесса.
Если эти подходы неприемлемы, вам придется идти вперед и реализовать небольшой синтаксический анализатор SQL, который может разделить файл на отдельные операторы. Это действительно сложно получить на 100% правильно, так как вам придется учитывать конкретные правила доступа к диалогам базы данных, используемую кодировку, любые параметры конфигурации базы данных, которые влияют на литеральный синтаксический анализ (например, PostgreSQL standard_conforming_strings).
Если вам нужно только получить этот 99,9% правильно, тогда некоторая магия регулярного выражения должна получить от вас большую часть пути.
Ответ 2
Если вы используете sqlite3, у него есть полезное расширение для dbapi, называемое conn.executescript(str), я подключил его через что-то вроде этого, и он, казалось, работал: (Не показан весь контекст, но этого должно быть достаточно для получения дрейфа)
def init_from_script(script):
Base.metadata.drop_all(db_engine)
Base.metadata.create_all(db_engine)
# HACK ALERT: we can do this using sqlite3 low level api, then reopen session.
f = open(script)
script_str = f.read().strip()
global db_session
db_session.close()
import sqlite3
conn = sqlite3.connect(db_file_name)
conn.executescript(script_str)
conn.commit()
db_session = Session()
Является ли это чистое зло? Я тщетно искал "чистый" sqlalchemy эквивалент, возможно, который мог быть добавлен в библиотеку, что-то вроде db_session.execute_script (имя_файла)? Я надеюсь, что db_session будет работать отлично после всего этого (т.е. Не нужно перезапускать движок), но пока не уверен... необходимы дальнейшие исследования (т.е. Нам нужно получить новый движок или просто сеанс после выхода за sqlalchemy назад?)
FYI sqlite3 включает связанную процедуру: sqlite3.complete_statement (sql), если вы катите свой собственный парсер...
Ответ 3
Мне удалось запустить файлы схемы .sql, используя чистую SQLAlchemy и некоторые строковые манипуляции. Это, конечно, не изящный подход, но он работает.
# Open the .sql file
sql_file = open(<file.sql>,'r')
# Create an empty command string
sql_command = ''
# Iterate over all lines in the sql file
for line in sql_file:
# Ignore comented lines
if not line.startswith('--') and line.strip('\n'):
# Append line to the command string
sql_command += line.strip('\n')
# If the command string ends with ';', it is a full statement
if sql_command.endswith(';'):
# Try to execute statemente and commit it
try:
session.execute(text(sql_command))
session.commit()
# Assert in case of error
except:
print('Ops')
# Finally, clear command string
finally:
sql_command = ''
Итерирует все строки в файле .sql, игнорируя прокомментированные строки. Затем он объединяет строки, которые образуют полный оператор и пытается выполнить оператор. Вам просто нужен обработчик файла и объект сеанса.