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