我正在将数据库从 sqlite 迁移到 mysql。现在我已经将数据迁移到 mysql,我无法使用我的 sqlalchemy 代码(在 Python3 中)在新的 mysql 数据库中访问它。我的印象是 sqlalchemy 语法与数据库无关(即相同的语法可用于访问 sqlite 和 mysql),但事实似乎并非如此。所以我的问题是:除了Sqlalchemy之外,是否绝对需要使用DBAPI来读取数据?我是否必须编辑所有 sqlalchemy 代码才能现在读取 mysql?
文档说:MySQL 方言使用 mysql-python 作为默认 DBAPI。有许多 MySQL DBAPI 可用,包括 MySQL-connector-python 和 OurSQL
,我认为这意味着我确实需要一个 DBAPI。
我使用 sqlite 的旧代码成功地与 sqlite 一起工作:
engine = create_engine('sqlite:///pmids_info.db')
def connection():
conn = engine.connect()
return conn
def load_tables():
metadata = MetaData(bind=engine) #init metadata. will be empty
metadata.reflect(engine) #retrieve db info for metadata (tables, columns, types)
inputPapers = Table('inputPapers', metadata)
return inputPapers
inputPapers = load_tables()
def db_inputPapers_retrieval(user_input):
result = engine.execute("select title, author, journal, pubdate, url from inputPapers where pmid = :0", [user_input])
for row in result:
title = row['title']
author = row['author']
journal = row['journal']
pubdate = row['pubdate']
url = row['url']
apa = str(author+' ('+pubdate+'). '+title+'. '+journal+'. Retrieved from '+url)
return apa
这工作得很好而且很花花公子。然后我尝试更新它以与 mysql 数据库一起使用,如下所示:
engine = create_engine('mysql://snarkshark@localhost/pmids_info')
起初,当我尝试像这样运行示例代码时,它会提示,因为我没有 MySqlDB
。一些谷歌搜索告诉我,MySqlDB
不适用于Python 3。所以然后我尝试pip安装pymysql
并将我的引擎语句更改为
engine = create_engine('mysql+pymysql://snarkshark@localhost/pmids_info')
当我尝试调整内容时,这最终也会给我带来各种语法错误。
所以我想知道的是,是否有任何方法可以让我当前的语法与 mysql 一起使用?由于语法来自 sqlalchemy,我认为它可以完美地处理 mysql 中与之前 sqlite 中完全相同的数据。我是否必须检查并更新所有数据库函数才能使用 DBAPI 的语法?
最佳答案
这听起来像是一个愚蠢的答案,但您需要更改所有使用特定于数据库的行为的地方。 SQLAlchemy 不保证您用它所做的任何事情都可以跨所有后端移植。它故意泄漏一些抽象,以允许您执行仅在某些后端可用的操作。你所做的就像使用Python,因为它是跨平台的,然后做一堆 os.fork()
到处都是,然后惊讶地发现它在 Windows 上不起作用。
对于您的具体情况,您至少需要将所有原始 SQL 包装在 text()
中。这样您就不会受到 DBAPI 支持的参数样式的影响。但是,不同 SQL 方言之间仍然存在细微差别,因此您需要使用 SQLAlchemy SQL expression language如果你想要可移植性,而不是原始 SQL。毕竟,您仍然需要小心,不要在 SQL 表达式语言中使用特定于后端的功能。
关于mysql - Python3、MySQL 和 SqlAlchemy — SqlAlchemy 是否始终需要 DBAPI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44338317/