Python3,MySQL和SqlAlchemy - SqlAlchemy总是需要DBAPI吗?

时间:2017-06-02 22:34:47

标签: mysql database python-3.x sqlite sqlalchemy

我正在将数据库从sqlite迁移到mysql。现在我已经将数据迁移到mysql,我无法使用我的sqlalchemy代码(在Python3中)在新的mysql db中访问它。我的印象是sqlalchemy语法与数据库无关(即相同的语法可用于访问sqlite和mysql),但似乎并非如此。所以我的问题是:除了Sqlalchemy之外,是否绝对需要使用DBAPI来读取数据?我是否必须编辑所有sqlalchemy代码才能读取mysql?

文档说:The MySQL dialect uses mysql-python as the default DBAPI. There are many MySQL DBAPIs available, including MySQL-connector-python and 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 db:

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,我认为它可以完美地用于以前在sqlite中的mysql中完全相同的数据。我是否必须通过并更新所有数据库函数才能使用DBAPI的语法?

1 个答案:

答案 0 :(得分:1)

这听起来像是一个愚蠢的答案,但您需要更改您使用特定于数据库的行为的所有地方。 SQLAlchemy不保证您使用它的任何可以在所有后端中移植。它会故意泄漏某些抽象 以允许您执行仅在某些后端上可用的操作。你正在做的就像使用Python一样,因为它是跨平台的,然后在任何地方做一堆os.fork(),然后惊讶于它在Windows上不起作用。 / p>

对于您的特定情况,您至少需要将所有原始SQL包装在text()中,这样您才不会受到DBAPI支持的参数样式的影响。但是,SQL的不同方言之间仍然存在细微差别,因此如果您想要可移植性,则需要使用SQLAlchemy SQL expression language而不是原始SQL。毕竟,您还需要注意不要在SQL表达式语言中使用特定于后端的功能。