Выполнить SQL из файла в SQLAlchemy - PullRequest
20 голосов
/ 15 февраля 2010

Как я могу выполнить весь файл sql в базу данных, используя SQLAlchemy? В файле может быть много разных SQL-запросов, включая begin и commit / rollback.

Ответы [ 5 ]

6 голосов
/ 23 августа 2016

Мне удалось запустить файлы схемы .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 commented 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 statement 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, игнорируя закомментированные строки. Затем он объединяет строки, которые образуют полный оператор, и пытается выполнить оператор. Вам просто нужен обработчик файла и объект сеанса.

4 голосов
/ 28 июня 2011

Если вы используете 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 (file_name)? Я надеюсь, что после всего этого db_session будет работать очень хорошо (то есть не нужно перезапускать движок), но пока не уверен ... необходимы дальнейшие исследования (то есть, нужно ли нам получить новый движок или просто сеанс после того, как за спиной sqlalchemy ?)

FYI sqlite3 включает связанную подпрограмму: sqlite3.complete_statement (sql), если вы катите свой собственный анализатор ...

4 голосов
/ 16 февраля 2010

К сожалению, я не знаю хорошего общего ответа на этот вопрос. Некоторые dbapi (например, psycopg2) поддерживают одновременное выполнение многих операторов. Если файлы не очень большие, вы можете просто загрузить их в строку и выполнить в соединении. Для других я бы попытался использовать клиент командной строки для этой базы данных и передать данные в нее с помощью модуля подпроцесса.

Если эти подходы неприемлемы, вам придется реализовать небольшой синтаксический анализатор SQL, который может разбить файл на отдельные операторы. Это действительно сложно получить на 100% правильно, так как вам придется учитывать конкретные экранирующие литералы правила базирования, используемый набор символов, любые параметры конфигурации базы данных, которые влияют на разбор литералов (например, PostgreSQL standard_conforming_strings).

Если вам нужно только исправить эти 99,9%, то некоторая магия регулярного выражения поможет вам в этом.

1 голос
/ 11 сентября 2018

Вы можете сделать это с помощью SQLalchemy и psycopg2.

file = open(path)
engine = sqlalchemy.create_engine(db_url)
escaped_sql = sqlalchemy.text(file.read())
engine.execute(escaped_sql)
0 голосов
/ 08 марта 2019

Вы можете получить доступ к необработанному соединению DBAPI через это

raw_connection = mySqlAlchemyEngine.raw_connection()
raw_cursor = raw_connection() #get a hold of the proxied DBAPI connection instance

но тогда это будет зависеть от того, какой диалект / драйвер вы используете, на который можно ссылаться в этом списке .

Для pyscog2 вы можете просто сделать

raw_cursor.execute(open("my_script.sql").read())

но pysqlite вам нужно будет сделать

raw_cursor.executescript(open("my_script").read())

и в соответствии с этим вам нужно будет проверить документацию к любому используемому вами драйверу DBAPI, чтобы увидеть, разрешено ли несколько операторов в одном выполнении или вам нужно использовать вспомогательный инструмент, такой как executescript, который уникален для pysqlite .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...