如何使用sqlalchemy + pyodbc和MS SQL Server中的多个数据库为pandas read_sql创建sql alchemy连接?

时间:2017-04-25 14:41:01

标签: python sql-server pandas sqlalchemy odbc

我正在尝试使用'pandas.read_sql_query'将数据从MS SQL Server复制到pandas DataFrame中。我需要在我的SQL查询中进行多个连接。要连接的表位于同一服务器上,但位于不同的数据库中。我传递给pandas的查询在MS SQL Server Management Studio中运行良好。在Jupyter笔记本中,我试图像这样查询数据(为了使事情可读,查询本身被简化为只有2个连接并使用了通用名称):

import pandas as pd
import sqlalchemy as sql
import pyodbc

server = '100.10.10.10'
driver = 'SQL+Server+Native+Client+11.0'
myQuery = '''SELECT first.Field1, second.Field2
           FROM db1.schema.Table1 AS first
           JOIN db2.schema.Table2 AS second
           ON first.Id = second.FirstId
           '''
engine = sql.create_engine('mssql+pyodbc://{}?driver={}'.format(server, driver))
df = pd.read_sql_query(myQuery, engine)

这不起作用并返回错误:

DBAPIError: (pyodbc.Error) ('IM010', '[IM010] [Microsoft][��������� ��������� ODBC] ������� ������� ��� ��������� ������ (0) (SQLDriverConnect)')

似乎问题在于引擎中没有包含有关数据库的信息,因为一切都可以正常使用下一种代码,我在引擎中包含了数据库:

myQuery = 'select Field1 from schema.Table1'
db = 'db1'
engine = sql.create_engine('mssql+pyodbc://{}/{}?driver={}'.format(server, db, driver))
df = pd.read_sql_query(myQuery, engine)

但如果我没有在引擎中包含数据库,则会像上面的联接一样中断,但是将其添加到查询中,如下所示:

myQuery = 'select Field1 from db1.schema.Table1'
engine = sql.create_engine('mssql+pyodbc://{}?driver={}'.format(server, 
driver))
df = pd.read_sql_query(myQuery, engine)

那么我应该如何指定pandas.read_sql_query的'sql'和'con'参数 这种情况,当我需要连接来自不同数据库但同一服务器的表时?

P.S。我只有对我连接的服务器的读访问权限。我不能创建新的表或视图或类似的东西。

更新: MS SQL Server版本为2008 R2。

更新2:我使用的是Python 3.6和Windows 10。

1 个答案:

答案 0 :(得分:5)

所以我找到了一个解决方法:使用pymssql而不是pyodbc(在import语句和引擎中)。它允许您使用数据库名称构建连接,而无需在引擎中指定它们。在这种情况下,无需指定驱动程序。

如果你使用的是python目前还不支持的Python 3.6,可能会出现问题,但你可以找到Python 3.6 here的非官方轮子。它适用于我的查询。

这是带有连接的原始代码,重建后可以使用pymssql:

import pandas as pd
import sqlalchemy as sql
import pymssql

server = '100.10.10.10'
myQuery = '''SELECT first.Field1, second.Field2
           FROM db1.schema.Table1 AS first
           JOIN db2.schema.Table2 AS second
           ON first.Id = second.FirstId'''
engine = sql.create_engine('mssql+pymssql://{}'.format(server))
df = pd.read_sql_query(myQuery, engine)

对于非官方的轮子,你需要从我上面给出的链接下载Python 3.6的文件,然后cd到下载文件夹并运行pip install wheels其中' wheels'是轮子文件的名称。

更新:

实际上,也可以使用pyodbc。我不确定这是否适用于任何SQL Server设置,但在我设置' master'之后,一切都适用于我。作为引擎中的数据库。生成的代码如下所示:

import pandas as pd
import sqlalchemy as sql
import pyodbc

server = '100.10.10.10'
driver = 'SQL+Server'
db = 'master'
myQuery = '''SELECT first.Field1, second.Field2
           FROM db1.schema.Table1 AS first
           JOIN db2.schema.Table2 AS second
           ON first.Id = second.FirstId'''
engine = sql.create_engine('mssql+pyodbc://{}/{}?driver={}'.format(server, db, driver))
df = pd.read_sql_query(myQuery, engine)