rmreで既存のRDBからActiveRecordモデルを生成する


他人の作成したデータベースはテーブルやキーの関係を解きほぐしてモデルを作成するのも大変なので、自動生成したいところです。rmreはデータベースからrails3のモデルを生成します。ChEMBLを例に、データベースモデルの生成をなぞります。

ChEMBL データベース

ChEMBLデータベースは、学術論文から化合物の活性を収集して作成されたものです。化合物、実験、活性値、ターゲットタンパク質、文献などの情報が含まれています。データベースのスキーマ図スキーマの説明を読むと関係がわかりますが、クエリを書く分には良いのですが、全体のモデルを作成するとなると、テーブルやキーが多いので気合いが要求されるものです。

データベースのセットアップ

PostgreSQL のダンプファイル (926MB) をダウンロードして、PostgreSQLにロードします。マシンスペック次第ですが、2時間から8時間程度でロードが完了すると思います。

ロードする時間が勿体ないというかたは、ロード済みの仮想マシンが配布(vmdk 9.5GB)されているので、そちらを利用することも可能です。

ここで ChEMBL 19のデータは、localhost:5432 の chembl_19 データベースに格納したとします。

モデルの生成

rmre は各種データベースに対応しているそうなので、-a オプションでここでは、postgresqlを指定します。生成したモデルは -o オプションで指定したディレクトリに1テーブル1ファイルで生成されます。


rmre -a postgresql -s localhost  --port 5432 -d chembl_19 -u postgres -o chembl_19_model

モデルファイルが chembl_19_model ディレクトリに生成されました。


$ ls chembl_19_model
action_type.rb              component_class.rb          drug_mechanism.rb           protein_classification.rb
activity.rb             component_domain.rb         formulation.rb              protein_family_classification.rb
activity_stds_lookup.rb         component_sequence.rb           ligand_eff.rb               relationship_type.rb
assay.rb                component_synonym.rb            mechanism_ref.rb            research_company.rb
assay_parameter.rb          compound_property.rb            molecule_atc_classification.rb      research_stem.rb
assay_type.rb               compound_record.rb          molecule_dictionary.rb          site_component.rb
atc_classification.rb           compound_structure.rb           molecule_hierarchy.rb           source.rb
binding_site.rb             confidence_score_lookup.rb      molecule_synonym.rb         target_component.rb
bio_component_sequence.rb       curation_lookup.rb          organism_class.rb           target_dictionary.rb
biotherapeutic.rb           data_validity_lookup.rb         parameter_type.rb           target_relation.rb
biotherapeutic_component.rb     defined_daily_dose.rb           predicted_binding_domain.rb     target_type.rb
cell_dictionary.rb          doc.rb                  product.rb              usan_stem.rb
chembl_id_lookup.rb         domain.rb               protein_class_synonym.rb        version.rb

assay テーブルの生成されたモデル定義 chembl_19_model/assay.rb を見ます。


class Assay > ActiveRecord::Base

    self.primary_key = :assay_id

    has_many :assay_parameters, :class_name => 'AssayParameter', :foreign_key => :assay_id    
    has_many :activities, :class_name => 'Activity', :foreign_key => :assay_id    
    belongs_to :assay_type, :class_name => 'AssayType', :foreign_key => :assay_type    
    belongs_to :cell_dictionary, :class_name => 'CellDictionary', :foreign_key => :cell_id    
    belongs_to :chembl_id_lookup, :class_name => 'ChemblIdLookup', :foreign_key => :chembl_id    
    belongs_to :confidence_score_lookup, :class_name => 'ConfidenceScoreLookup', :foreign_key => :confidence_score    
    belongs_to :curation_lookup, :class_name => 'CurationLookup', :foreign_key => :curated_by    
    belongs_to :doc, :class_name => 'Doc', :foreign_key => :doc_id    
    belongs_to :relationship_type, :class_name => 'RelationshipType', :foreign_key => :relationship_type    
    belongs_to :source, :class_name => 'Source', :foreign_key => :src_id    
    belongs_to :target_dictionary, :class_name => 'TargetDictionary', :foreign_key => :tid    
end

primary_key、belongs_to、has_manyなどが定義されたことがわかります。

クエリ例

接続とセットアップ、全ての生成されたモデルファイルをrequireします。


require 'active_record'
ActiveRecord::Base.establish_connection( {:adapter => 'postgresql', 
                                          :host => 'localhost',
                                          :port => 5432,
                                          :username => 'postgres', 
                                          :password => '', 
                                          :database => 'chembl_19'} )
dir = File.join('chembl_19_model', '*.rb')
Dir.glob(dir) { |file| require file }

Assayの説明の取得、ID 1 のAssayレコードを取得して説明を表示します。


irb(main):004:0> Assay.find(1).description
=> "The compound was tested for the in vitro inhibition of platelet 12-lipoxygenase at a concentration of 30 uM"

Assayの活性値の数


irb(main):006:0> Assay.find(1).activities.size
=> 1

Assayタイプの説明


irb(main):009:0> Assay.find(1).assay_type.assay_desc
=> "Binding"

Assayのターゲットの名前


irb(main):003:0> Assay.find(1).target_dictionary.pref_name
=> "Arachidonate 12-lipoxygenase"

複数のテーブルのJOINが必要なクエリでも、ActivieRecordで簡単にクエリが書けるようになりました。

まとめ

rmreで既存のRDBからモデルを自動生成してみました。
生成したモデルでクエリを試しました。

研究に利用する場合は、生成したモデルとスキーマを照らし合わせて確認し、必要に会わせてモデルファイルを修正することや、メソッドを追加する必要があるかもしれません。