2

pypyodbc は .accdb データベース内のリンクされたテーブルにどのように接続できますか? これはまったく可能ですか、それとも pyodbc の制限ですか?

MS Acess .accdb データベースから Python にデータを取得する必要があります。これは完全に機能しpypyodbc、.accdb データベース内で定義されたテーブルとクエリにアクセスするために使用できます。ただし、データベースには、外部 SQL Server にリンクされたテーブルもあります。このようなリンクされたテーブルにアクセスpypyodbcすると、SQL サーバーに接続できないと訴えます。

test.accdbTest(ローカル テーブル) とcidb_ain(リンクされた SQL テーブル)の2 つのテーブルが含まれています。

次の Python 3 コードは、データにアクセスしようとする試みです。

import pypyodbc as pyodbc

cnxn = pyodbc.connect(driver='Microsoft Access Driver (*.mdb, *.accdb)',
                      dbq='test.accdb',
                      readonly=True)

cursor = cnxn.cursor()

# access to the local table works
for row in cursor.execute("select * from Test"):
    print(row)

print('----')

# access to the linked table fails
for row in cursor.execute("select * from cidb_ain"):
    print(row)

出力:

(1, 'eins', 1)
(2, 'zwei', 2)
(3, 'drei', 3)
----
Traceback (most recent call last):
  File "test_02_accdb.py", line 14, in <module>
    for row in cursor.execute("select * from cidb_ain"):
  File "C:\software\installed\miniconda3\lib\site-packages\pypyodbc.py", line 1605, in execute
    self.execdirect(query_string)
  File "C:\software\installed\miniconda3\lib\site-packages\pypyodbc.py", line 1631, in execdirect
    check_success(self, ret)
  File "C:\software\installed\miniconda3\lib\site-packages\pypyodbc.py", line 986, in check_success
    ctrl_err(SQL_HANDLE_STMT, ODBC_obj.stmt_h, ret, ODBC_obj.ansi)
  File "C:\software\installed\miniconda3\lib\site-packages\pypyodbc.py", line 964, in ctrl_err
    raise Error(state,err_text)
pypyodbc.Error: ('HY000', "[HY000] [Microsoft][ODBC-Treiber für Microsoft Access] ODBC-Verbindung zu 'SQL Server Native Client 11.0SQLHOST' fehlgeschlagen.")

エラー メッセージは、大まかに「'SQL Server Native Client 11.0SQLHOST' への ODBC 接続に失敗しました」と訳されます。

pypyodbc を使用して .accdb データベースを介して SQL Server にアクセスすることはできませんが、cidb_ainMS Access 内からテーブルをクエリすることは可能です。さらに、SQL Server に直接接続できます。

cnxn = pyodbc.connect(driver='SQL Server Native Client 11.0',
                      server='SQLHOST',
                      trusted_connection='yes',
                      database='stuffdb')

(1)MS Access(およびMatlabも)が.accdbファイルに含まれる情報を使用してリンクされたテーブルを照会できること、および(2)SQL Serverにアクセスできることを考慮すると、問題はに関連していると思いますpypyodbc. (エラーメッセージでドライバ名とホスト名がめちゃくちゃにされている方法'SQL Server Native Client 11.0SQLHOST'も、やや疑わしいようです。)

私は以前に Access を使用したことがないので、しばらくお待ちください。不要と思われる重要な情報を省略した場合はお知らせください...

4

2 に答える 2

1

まず、MS Access は、他の RDMS (SQLite、MySQL、PostgreSQL、Oracle、DB2 など) とは多少異なる独自のタイプのデータベース アプリケーションですこの方法は、アクセス制限されたコンポーネントではなく、一般的な Microsoft テクノロジ) と、フロントエンドGUI インターフェイスおよびレポート ジェネレータです。基本的に、Access はオブジェクトのコレクションです。

リンク テーブルは、別のバックエンド データベース、特に SQL Server 用のデフォルトの Jet/ACE データベース (つまり、ローカル テーブル) を置き換えるために使用される MS Access のフロントエンド側の機能の一部です。さらに、リンクされたテーブルは ODBC/OLEDB 接続そのものです! MS Access ファイルでリンク テーブルを確立および作成するには、DSN、ドライバー、またはプロバイダーを使用する必要がありました。

したがって、MS Access データベース [ driver='Microsoft Access Driver (*.mdb, *.accdb)] に接続する外部クライアント (ここでは Python スクリプト) は、実際にはバックエンドの Jet/ACE データベースに接続しています。クライアント/スクリプトがフロントエンド オブジェクトと対話することはありません。あなたのエラーでは、Python はリンクされたテーブルの ODBC 接続を読み取り、SQL Server Driver/Provider [ SQL Server Native Client 11.0SQLHOST] がスクリプトで呼び出されることはないため、スクリプトは失敗します。

全体として、状況を解決するには、Python を SQL Server データベースに直接接続して (MS Access を媒体として使用しないで)、そこにあるローカル テーブルに接続する必要がありますcidb_ain。Access リンク テーブルの接続文字列を使用するだけです。

#(USING DSN)
db = pypyodbc.connect('DSN=dsn name;')

cur = db.cursor()
cur.execute("SELECT * FROM dbo.cidb_ain")

for row in cur.fetchall()
  print(row)

cur.close()
db.close()


# (USING DRIVER)
constr = 'Trusted_Connection=yes;DRIVER={SQL Server};SERVER=servername;' \
         'DATABASE=database name;UID=username;PWD=password'
db = pypyodbc.connect(constr)

cur = db.cursor()
cur.execute("SELECT * FROM dbo.cidb_ain")

for row in cur.fetchall()
  print(row)

cur.close()
db.close()
于 2015-09-23T19:35:55.893 に答える
1

アップデート:

この問題の解決策はpyodbc.pooling = False、Access データベースへの接続を確立する前に設定するのと同じくらい簡単です。

import pyodbc
# ... also works with `import pypyodbc as pyodbc`, too
pyodbc.pooling = False  # this prevents the error
cnxn = pyodbc.connect(r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ= ... ")


(以前の回答)

pypyodbc も pyodbc も、Access データベースから SQL Server リンク テーブルを読み取ることができないようです。ただし、  System.Data.Odbc .NET で実行できるので、IronPythonでも実行できます。

確認するために、SQL Server に [Foods] という名前のテーブルを作成しました

id  guestId  food
--  -------  ----
 1        1  pie
 2        2  soup

Access で [dbo_Foods] という名前の ODBC リンク テーブルを作成し、SQL Server 上のそのテーブルを参照しました。

[Guests] という名前のローカル Access テーブルも作成しました...

id  firstName
--  ---------
 1  Gord
 2  Jenn

... [qryGuestPreferences] という名前の保存された Access クエリ ...

SELECT Guests.firstName, dbo_Foods.food
FROM Guests INNER JOIN dbo_Foods ON Guests.id = dbo_Foods.guestId;

IronPython で次のスクリプトを実行すると ...

import clr
import System
clr.AddReference("System.Data")
from System.Data.Odbc import OdbcConnection, OdbcCommand

connectString = (
    r"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};"
    r"DBQ=C:\Users\Public\Database1.accdb;"
)
conn = OdbcConnection(connectString)
conn.Open()

query = """\
SELECT firstName, food 
FROM qryGuestPreferences
"""
cmd = OdbcCommand(query, conn)
rdr = cmd.ExecuteReader()
while rdr.Read():
    print("{0} likes {1}.".format(rdr["firstName"], rdr["food"]))
conn.Close()

... 戻り値

Gord likes pie.
Jenn likes soup.
于 2015-09-26T15:54:52.857 に答える