前提
pyhtonを実行するサーバーとSQL Serverを搭載しているサーバーは別に設置しています。この2つはともにWindows Server 2016です。
python実行サーバー ⇒ Aサーバー
SQL Server搭載サーバー ⇒ Bサーバー
該当のソースコード
Aサーバーのpythonプログラムから、BサーバーにあるSQL Serverのテーブルにデータを格納するコードを書いています。
以下はpythonプログラム(SQLACCESS.py)のコードです。
import pyodbc import pandas as pd import settings import pymssql import csv from sqlalchemy import create_engine # インスタンス instance = "インスタンス名" # ユーザー user = "ユーザー名" # パスワード pasword = "パスワード" # ポート port = "ポート番号" #データベース database = "データベース名" #CSVファイルパス file = "C:\\Users\\***\\***\\***\\access_test.csv" #テーブル名 table = "テーブル名" # DB接続 connection = ( 'DRIVER={SQL Server};SERVER='+instance + ';DATABASE='+database+';UID='+user+';PWD='+ pasword + ';' ) con = pyodbc.connect(connection, autocommit=True) cursor = con.cursor() #CSVを読み込み、データフレーム化 csv = pd.read_csv(file, encoding='utf-8-sig') df = pd.DataFrame(csv) #テーブルに格納されているデータを全て削除 cursor.execute("TRUNCATE TABLE " + table) con.commit() #データフレームのままSQLServerに格納する engine = create_engine(f"mssql+pymssql://{user}:{pasword}@{instance}/{database}") df.to_sql('Access_test', con = engine, if_exists='replace', index=None) con.commit() # DB切断 cursor.close() con.close()
発生している問題・エラーメッセージ
以下のエラーが表示され、データ格納できませんでした。
接続情報に間違いはございません。
エラーメッセージ Traceback (most recent call last): File "c:\Users\***\***\***\SQLACCESS.py", line 38, in <module> con = pyodbc.connect(connection, autocommit=True) pyodbc.OperationalError: ('08001', '[08001] [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server が存在しないか、アクセスが拒否されました。 (17) (SQLDriverConnect); [08001] [Microsoft][ODBC SQL Server Driver][DBNETLIB]ConnectionOpen (Connect()). (53)')
質問
pyhton実行サーバー(Aサーバー)のpythonプログラムから、SQL Server搭載サーバー(Bサーバー)にあるSQL Serverのテーブルにデータを格納するためにはどうしたらよいでしょうか。一方、pythonプログラムをクライアントPCから実行すると、格納できることは確認しています。
> 一方、pythonプログラムをクライアントPCから実行すると、格納できることは確認しています。
「クライアントPC」って何ですか? 「Aサーバー」「Bサーバー」とどういう関係にあるのですか?
connection = (
'DRIVER={SQL Server};SERVER='+instance + ';DATABASE='+database+';UID='+user+';PWD='+ pasword + ';'
)
コネクションの部分ですが、ポート番号が指定されていません。DB サーバがデフォルトのポート番号を使用しているのであれば問題ないのですが、それ以外の番号を使用しているということはありませんか?
SQL Server のバージョン・エディションは何ですか? Express 版をデフォルトでインストールしたとかじゃないでしょうね?
接続に失敗しています。53だと恐らく
https://learn.microsoft.com/ja-jp/windows/win32/debug/system-error-codes--0-499-
ERROR_BAD_NETPATH
53 (0x35)
ネットワーク パスが見つかりませんでした。
だと思います。ODBCの接続文字列だとserver=は
ホスト名\インスタンス名
のような形でないといけないかもしれません(ポートないし)。
接続文字列の調べ方については、以下も参考になるかもしれません。
https://learn.microsoft.com/ja-jp/sql/integration-services/import-export-data/connect-to-an-odbc-data-source-sql-server-import-and-export-wizard?view=sql-server-ver16
みなさま
コメントありがとうございます。
コメントいただきました内容を元に検証を進めております。検証結果がわかり次第、ご報告させていただきます。
また、ご質問いただきました内容の回答は、下記の通りです。
>「クライアントPC」って何ですか? 「Aサーバー」「Bサーバー」とどういう関係にあるのですか?
「クライアントPC」とは「Aサーバー」の代わりとして使用したパソコン(Windows 10 Pro)のことです。「クライアントPC」からpythonプログラムを実行すると「Bサーバー」へのデータ格納は成功しましたが、「Aサーバー」からpythonプログラムを実行すると「Bサーバー」へのデータ格納は失敗しました。
>SQL Server のバージョン・エディションは何ですか?
「Bサーバー」にインストールしたSQL Server のバージョン・エディションは、下記の通りです。
バージョン:13.0.5888.11
エディション:Microsoft SQL Server Standard (64-bit)
エラーメッセージから「Aサーバー」の Python アプリが「Bサーバー」の SQL Server に
(1) 接続できない、もしくは
(2) ログインできない
・・・ということになると思うのですが。「クライアントPC」の Python アプリの接続文字列は「Aサーバー」の Python アプリと同じで、SQL Server の認証の問題はない(=ログインできないということはない)ということですか?
ご質問に回答いたします。
>「クライアントPC」の Python アプリの接続文字列は「Aサーバー」の Python アプリと同じで、SQL Server の認証の問題はない(=ログインできないということはない)ということですか?
ご記載のとおりでございます。
とすると、「Aサーバー」が「Bサーバー」と同じ LAN 内に無いとか、接続文字列 SERVER='+instance + ' ... の instance で名前解決ができないということが思い浮かびますが、そういうことはないのでしょうか?
回答2件
あなたの回答
tips
プレビュー