BH12.12/SPARQLthon10/VirtuosoPL
提供:TogoWiki
以下2つの目的でVirtuosoのストアドプロシージャ言語であるVirtuoso/PLを調査した。
- ロード処理のバッチ化
- 集約関数など遅いSPARQLの計算結果をトリプルで出力してインポートする処理を自動化
目次 |
プロシージャの作成・更新手順
作成
isqlからCREATE PROCEDURE文で宣言する。
SQL> CREATE PROCEDURE ユーザ.PROCEDURE名 ( 引数 ) { //本文 };
確認
コマンドでの確認方法は不明。
conductorから[Database] - [DB] - [Procedures]。 確認したいプロシージャの[Edit]を押して確認する。
更新
上記conductorからそのまま編集しするか、 同じPROCEDURE名でCREATE文を書くと更新される。
PROCEDURE名の変更は削除 + CREATEでやり直す。
削除
conductorから削除したいPROCEDUREを選択し、リスト下の[Drop Selected]を押下する。
ログ出力
ログをファイルに出力するサンプルプロシージャ
- プロシージャコード
CREATE PROCEDURE DB.DBA.MSG_LOG ( IN in_module VARCHAR , IN in_message VARCHAR ) { DECLARE log_path VARCHAR; log_path := './log/togo_' || cast(curdate() as VARCHAR) || '.log'; string_to_file(log_path,sprintf('%s(%s)->%s\n',in_module,CAST (NOW() AS VARCHAR),in_message),-1); }
- 呼び出し
MSG_LOG('MyModule', 'Hello!');
- 結果
%VirtuosoHOME/log/togo_2013-07-29.log
MyModule(2013-07-29 11:07:36.000019)->Hello!
データロード
グラフ毎に、クリア + ロードするプロシージャ例
ディレクトリ一括ロード
- プロシージャコード
CREATE PROCEDURE DB.DBA.MICROBEDB_LOAD_BRC ( IN rdf_dir VARCHAR, IN graph_name VARCHAR ) { MSG_LOG('LOAD_BRC', 'START'); -- CLEAR GRAPH MSG_LOG('LOAD_BRC', 'CLEAR GRAPH START'); log_enable(3,1); SPARQL CLEAR GRAPH ?:graph_name; MSG_LOG('LOAD_BRC', 'CLEAR GRAPH END'); -- LOAD GRAPH MSG_LOG('LOAD_BRC', 'LOAD START'); DELETE FROM DB.DBA.LOAD_LIST WHERE ll_graph = graph_name; ld_dir(sprintf('%s%s',rdf_dir , 'brc/jcm'), '*.ttl', graph_name); rdf_loader_run(); ld_dir(sprintf('%s%s',rdf_dir , 'brc/nbrc'), '*.ttl', graph_name); rdf_loader_run(); MSG_LOG('LOAD_BRC', 'END'); }
- 呼び出し
cl_exec('checkpoint'); checkpoint_interval(6000);//ロードサイズが大きい場合はチェックポイント間隔を広げる DB.DBA.MICROBEDB_LOAD_BRC('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/brc/'); cl_exec('checkpoint'); checkpoint_interval(60);//デフォルト値に戻す
TTLロード
- プロシージャコード
CREATE PROCEDURE DB.DBA.MICROBEDB_LOAD_GOLD ( IN rdf_dir VARCHAR, IN graph_name VARCHAR ) { MSG_LOG('LOAD_GOLD', 'START'); -- CLEAR GRAPH MSG_LOG('LOAD_GOLD', 'CLEAR GRAPH START'); log_enable(3,1); SPARQL CLEAR GRAPH ?:graph_name; MSG_LOG('LOAD_GOLD', 'CLEAR GRAPH END'); -- LOAD GRAPH MSG_LOG('LOAD_GOLD', 'LOAD gold2meo.ttl START'); DB.DBA.TTLP_MT (file_to_string_output(sprintf('%s%s',rdf_dir , 'ontology/gold/gold2meo.ttl')), '', graph_name); MSG_LOG('LOAD_GOLD', 'LOAD gold2mpo.ttl START'); DB.DBA.TTLP_MT (file_to_string_output(sprintf('%s%s',rdf_dir , 'ontology/gold/gold2mpo.ttl')), '', graph_name); MSG_LOG('LOAD_GOLD', 'LOAD gold2taxon.ttl START'); DB.DBA.TTLP_MT (file_to_string_output(sprintf('%s%s',rdf_dir , 'ontology/gold/gold2taxon.ttl')), '', graph_name); MSG_LOG('LOAD_GOLD', 'END'); }
- 呼び出し
cl_exec('checkpoint'); DB.DBA.MICROBEDB_LOAD_GOLD('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/gold/'); cl_exec('checkpoint');
RDF/XMLロード
- プロシージャコード
CREATE PROCEDURE DB.DBA.MICROBEDB_LOAD_NCBITAXON ( IN rdf_dir VARCHAR, IN graph_name VARCHAR ) { MSG_LOG('LOAD_NCBITAXON', 'START'); -- CLEAR GRAPH MSG_LOG('LOAD_NCBITAXON', 'CLEAR GRAPH START'); log_enable(3,1); SPARQL CLEAR GRAPH ?:graph_name; MSG_LOG('LOAD_NCBITAXON', 'CLEAR GRAPH END'); -- LOAD GRAPH MSG_LOG('LOAD_NCBITAXON', 'LOAD START'); DB.DBA.RDF_LOAD_RDFXML_MT(file_to_string_output(sprintf('%s%s',rdf_dir , 'ontology/ncbitaxon/ncbitaxon.owl')), '', graph_name); MSG_LOG('LOAD_NCBITAXON', 'END'); }
- 呼び出し
cl_exec('checkpoint'); DB.DBA.MICROBEDB_LOAD_NCBITAXON('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/ncbitaxon/'); cl_exec('checkpoint');
全グラフロード
- プロシージャコード
CREATE PROCEDURE DB.DBA.MICROBEDB_LOAD_ALL_GRAPH() { MSG_LOG('LOAD_ALL_GRAPH', 'START'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT1', 'START'); cl_exec('checkpoint'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT1', 'END'); checkpoint_interval(6000); DB.DBA.MICROBEDB_LOAD_REFSEQ('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/refseq/'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT2', 'START'); cl_exec('checkpoint'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT2', 'END'); DB.DBA.MICROBEDB_LOAD_GTPS('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/gtps/'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT3', 'START'); cl_exec('checkpoint'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT3', 'END'); DB.DBA.MICROBEDB_LOAD_MBGD('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/mbgd/'); DB.DBA.MICROBEDB_LOAD_BRC('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/brc/'); DB.DBA.MICROBEDB_LOAD_GO('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/go/'); DB.DBA.MICROBEDB_LOAD_SO('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/so/'); DB.DBA.MICROBEDB_LOAD_NCBITAXON('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/ncbitaxon/'); DB.DBA.MICROBEDB_LOAD_GOLD('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/gold/'); DB.DBA.MICROBEDB_LOAD_MEO('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/meo/'); DB.DBA.MICROBEDB_LOAD_MPO('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/mpo/'); DB.DBA.MICROBEDB_LOAD_MCCV('/usr/local/var/lib/virtuoso/db/RDF/','http://microbedb.jp/mccv/'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT4', 'START'); cl_exec('checkpoint'); MSG_LOG('LOAD_ALL_GRAPH_CHECKPOINT4', 'END'); checkpoint_interval(60); DMSG_LOG('LOAD_ALL_GRAPH', 'END'); }
- 呼び出し
DB.DBA.MICROBEDB_LOAD_ALL_GRAPH();
集約データの作成
Taxonomy(BioProject)毎のGene数の集計
- プロシージャコード
CREATE PROCEDURE DB.DBA.MICROBEDB_CREATE_REFSEQ_GENE_COUNT_TTL ( IN out_file VARCHAR ) RETURNS INTEGER { DECLARE file_name VARCHAR; DECLARE env, ses ANY; SET ISOLATION = 'uncommitted'; file_name := sprintf ('%s.ttl', out_file); env := vector (dict_new (16000), 0, '', '', '', 0, 0, 0, 0); ses := string_output (); env := (SPARQL DEFINE output:format "NT" DEFINE sql:select-option "order" PREFIX obo: <http://purl.obolibrary.org/obo/> PREFIX insdc: <http://insdc.org/owl/> PREFIX idorg:<http://rdf.identifiers.org/database/> CONSTRUCT { ?tax <gene_count> [ rdfs:seeAlso ?bioProject; <gene_number> ?num_gene; <rrna_number> ?num_rrna; <trna_number> ?num_trna; ]. } FROM <http://microbedb.jp/refseq/> WHERE { SELECT ?tax ?bioProject COUNT(?gene) as ?num_gene COUNT(?rrna) AS ?num_rrna COUNT(?trna) AS ?num_trna FROM <http://microbedb.jp/refseq/> WHERE { ?tax rdf:type idorg:Taxonomy . ?seq rdfs:seeAlso ?tax ; rdf:type ?obo_type FILTER(?obo_type IN (obo:SO_0000340, obo:SO_0000155 )). ?seq rdfs:seeAlso ?bioProject. ?bioProject rdf:type idorg:BioProject . { ?gene obo:so_part_of ?seq ; rdf:type obo:SO_0000704 . } UNION { ?rrna obo:so_part_of ?seq ; rdf:type obo:SO_0000252 . } UNION { ?trna obo:so_part_of ?seq ; rdf:type obo:SO_0000253 . } } GROUP BY ?tax ?bioProject } ); string_to_file (file_name, env,-1); return 0; }
- 呼び出し
DB.DBA.MICROBEDB_CREATE_REFSEQ_GENE_COUNT_TTL('prop_test/hogehoge');
課題
エラー制御
エラー発生時に処理を続行するか中断するかの制御が必要。
以下のコードは何かのエラー(全エラーコード)発生時にログを出力し、処理を続行する例。プロシージャの先頭あたり記載する。細かい制御は難しそう。
DECLARE CONTINUE HANDLER FOR SQLSTATE '*' { MSG_LOG('DUMP','ERROR IN DUMP_MEO'); };
トリプル出力数制限
CONSTRUCT文の出力はvirtuoso.iniのResultSetMaxRows(デフォルト:10000)が出力上限になる。
上記のMICROBEDB_CREATE_REFSEQ_GENE_COUNT_TTLだと、CONSTRUCTで5トリプル吐き出すので、2000データしか出てこない。
ResultSetMaxRowsの上限を無暗に上げるとサーバ負荷が上がるため、Taxonomyの数だけSPARQLをループで回して出力する方法を検討中。
OFFSETを使って出力数を抑える考えもあるが、OFFSETに対して変数がセットできないバグがある?
http://www.mail-archive.com/virtuoso-users%40lists.sourceforge.net/msg02363.html