web-dev-qa-db-ja.com

pandas read_sql with sqlalchemy + pyodbcおよびMSSQL Serverの複数のデータベースのSQLalchemy接続を作成するにはどうすればよいですか?

'pandas.read_sql_query'を使用してデータをMSSQLServerからpandas DataFrameにコピーしようとしています。SQLクエリで複数の結合を行う必要があります。結合されるテーブルは同じ上にありますサーバーですが、データベースが異なります。pandasは、MS SQL Server Management Studio内で正常に機能します。JupyterNotebookでは、そのようにデータをクエリしようとしました(クエリ自体を読みやすくするため)は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 SQLServerのバージョンは2008R2です。

アップデート2:Python 3.6とWindows10を使用しています。

5
Sergey Zakharov

だから私は回避策を見つけました:pyodbcの代わりにpymssqlを使用してください(importステートメントとエンジンの両方で)。これにより、データベース名を使用して、エンジンで指定せずに結合を構築できます。この場合、ドライバーを指定する必要はありません。

PymssqlでまだサポートされていないPython 3.6を使用している場合は問題が発生する可能性がありますが、Python 3.6- ここ 。それは私のクエリで想定されているように機能します。

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のファイルをダウンロードしてから、ダウンロードフォルダーに移動し、pip install wheelsを実行する必要があります。ここで「wheels」はホイールファイルの名前。

更新:

実際には、pyodbcを使用することも可能です。これがSQLServerのセットアップで機能するかどうかはわかりませんが、エンジンのデータベースとして「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)
5
Sergey Zakharov