Szy*_*ski 22 sql database sqlalchemy
如何使用SQLAlchemy将整个sql文件执行到数据库中?文件中可以有许多不同的sql查询,包括begin和commit/rollback.
您可以使用 SQLalchemy 和 psycopg2 来完成。
file = open(path)
engine = sqlalchemy.create_engine(db_url)
escaped_sql = sqlalchemy.text(file.read())
engine.execute(escaped_sql)
Run Code Online (Sandbox Code Playgroud)
小智 7
我能够使用纯SQLAlchemy和一些字符串操作来运行.sql模式文件.它肯定不是一个优雅的方法,但它的工作原理.
# 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 = ''
Run Code Online (Sandbox Code Playgroud)
它遍历.sql文件中忽略注释行的所有行.然后它连接形成完整语句的行并尝试执行该语句.您只需要一个文件处理程序和一个会话对象.
sqlalchemy.sql.text.sql通过使用内置text构造,有一种更直接的方法来执行文件。
from sqlalchemy import create_engine
from sqlalchemy.sql import text
engine = create_engine('mysql://{USR}:{PWD}@localhost:3306/db', echo=True)
with engine.connect() as con:
file = open("src/models/query.sql")
query = text(file.read())
con.execute(query)
Run Code Online (Sandbox Code Playgroud)
不幸的是,我没有一个好的通用答案。某些dbapi(例如psycopg2)支持一次执行许多语句。如果文件不是很大,您可以将它们加载到字符串中并在连接上执行它们。对于其他用户,我将尝试为该数据库使用命令行客户端,并使用subprocess模块将数据通过管道传递给该客户端。
如果这些方法不可接受,则必须继续执行一个小型SQL解析器,该解析器可以将文件拆分为单独的语句。要确保100%正确,这确实很棘手,因为您必须考虑数据库方言特定的文字转义规则,所使用的字符集以及任何影响文字解析的数据库配置选项(例如PostgreSQL standard_conforming_strings)。
如果您只需要99.9%的正确率,那么一些正则表达式魔术应该可以帮助您达到目标。
如果您使用的是 sqlite3,它有一个名为 conn.executescript(str) 的有用的 dbapi 扩展,我已经通过类似这样的东西将其连接起来,它似乎有效:(未显示所有上下文,但它应该足以获得漂移)
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()
Run Code Online (Sandbox Code Playgroud)
我想知道这是纯粹的邪恶吗?我徒劳地寻找“纯”sqlalchemy 等价物,也许可以将其添加到库中,例如 db_session.execute_script(file_name) ?我希望 db_session 在这一切之后能够正常工作(即不需要重新启动引擎)但还不确定......需要进一步研究(即我们是否需要获得一个新引擎或只是在 sqlalchemy 背后进行一次会话?)
仅供参考 sqlite3 包括一个相关的例程: sqlite3.complete_statement(sql) 如果您使用自己的解析器...
您可以通过此访问原始 DBAPI 连接
raw_connection = mySqlAlchemyEngine.raw_connection()
raw_cursor = raw_connection() #get a hold of the proxied DBAPI connection instance
Run Code Online (Sandbox Code Playgroud)
但这取决于您使用的方言/驱动程序,可以通过此列表进行参考。
对于 pyscog2,你可以这样做
raw_cursor.execute(open("my_script.sql").read())
Run Code Online (Sandbox Code Playgroud)
但是 pysqlite 你需要做
raw_cursor.executescript(open("my_script").read())
Run Code Online (Sandbox Code Playgroud)
根据这一点,您需要检查您正在使用的 DBAPI 驱动程序的文档,以查看一次执行中是否允许多个语句,或者您是否需要使用executescriptpysqlite 特有的帮助程序。