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