3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

記事投稿キャンペーン 「2024年!初アウトプットをしよう」

Virtuoso (VOS) にODBCを用いてSPARQLで問い合わせる

Last updated at Posted at 2024-01-06

トリプルストアの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)')
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?