トリプルストアのVirtuoso Open-Source Edition (VOS)に対しては多くの場合、SPARQLエンドポイントとしてHTTP(S)を用いてアクセスし、所望のデータを取得する。しかし、検索対象のデータサイズが大きい場合、特に複雑なクエリや大量の結果が得られるクエリの処理に時間がかかり、タイムアウトすることがある。一方でVOSはODBCに対応しているので、これを利用して問い合わせると検索時間が短く、SPARQLエンドポイント経由では取得できないクエリでも結果が得られることが多い。
なお、ODBCを利用してアクセスするまでに必要な作業はOSごとに異なるので、今回はLinuxを対象とし、pythonのpyodbcを利用した手順を記載する。管理者権限は不要。今回動作確認した環境は以下の通り。
- VOS 7.2.6
- CentOS7
- Python 3.9.6
- pyodbc-5.0.1
1. VOSのODBCドライバの存在を確認する
VOSをダウンロードして適切に配置すると、lib/virtodbcu_r.so
が置かれるので、確認する。
2. .odbc.ini を設置する
下記の内容と同等の項目を記載したファイル .odbc.ini
を ${HOME}
直下に置く。[
と]
に囲まれた冒頭部分の文字列は、後にPythonスクリプト内で利用するための識別子になる。また、Description
の内容は任意。Driver
に対しては、VOS配置後に置かれるvirtodbcu_r.so
の絶対パスを記載する。Address
はSPARQLで問合せたいVOSのネット上の所在を記載する。なお、本記事で21650
としているポート番号は、特にvirtuoso.ini
を編集するなどしない限り、1111
が初期値である。さらに、プログラムとVOSの間でやり取りする際に用いる文字コードに関する設定としてwideAsUTF16
に対する値をY
とする。参考文献としてVOS開発元による記事がある。
[MyVirtuosoDSN]
Description = Virtuoso ODBC Data Source
Driver = /data/vos726/lib/virtodbcu_r.so
Address = localhost:21650
wideAsUTF16 = Y
3. pyodbcをインストールする
こちらを参照するなどしてインストールする。通常は、pip install pyodbc
で事足りるが、環境によってはpyodbcの文書に書かれている通り、次のようなエラーが生じることがある。
ImportError: libodbc.so.2: cannot open shared object file: No such file or directory
その場合は同文書に書いてある通り、下記の要領でunixodbc
をインストールする。この作業は残念ながら管理者権限が必要になるので、sudoersではないなら適宜権限のある利用者にお願いする。
$ sudo apt install unixodbc
もしくは
$ sudo yum -y install unixODBC unixODBC-devel
4. プログラムを書いてみる
下記のプログラム(query_vos.py
)などを参考に、動作確認プログラムを書く。conn_string
に与える文字列冒頭部分に、DSN=MyVirtuosoDSN
と書かれているが、これを、上記の.odbc.ini
冒頭部に書かれている内容と一致させることが重要。また、SPARQLクエリをVOSに認識させるためには、クエリの冒頭に、SPARQL
と記載する。そうでない場合は、SQLクエリとして認識される。
import pyodbc
# ODBC接続の準備
conn_string = "DSN=MyVirtuosoDSN;UID=dba;PWD=dba"
conn = pyodbc.connect(conn_string)
# やり取りする文字コードの設定 (pyodbc 5では不要)
conn.setdecoding(pyodbc.SQL_CHAR, encoding="utf-8")
conn.setdecoding(pyodbc.SQL_WCHAR, encoding="utf-8")
conn.setencoding(encoding="utf8")
# カーソル生成
cursor = conn.cursor()
# クエリ実行
query = 'SPARQL select distinct ?class {[] a ?class}'
cursor.execute(query)
# 結果の表示
for row in cursor.fetchall():
print(row)
# 接続の解除
conn.close()
5. 起こりがちなエラーとその原因
a. .odbc.ini
が適切に配置されていない場合は以下のエラーメッセージが表示される。
Traceback (most recent call last):
File "query_vos.py", line 7, in <module>
conn = pyodbc.connect(conn_string)
pyodbc.InterfaceError: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')
b. 文字コード周りの設定が適切になされていない場合は、以下のエラーメッセージが表示される。
Traceback (most recent call last):
File "query_vos.py", line 18, in <module>
cursor.execute(query)
pyodbc.ProgrammingError: ('42000', '[42000] [OpenLink][Virtuoso ODBC Driver][Virtuoso Server]SQ074: Line 1: Too many closing parentheses (-1) (SQLExecDirectW)')