メタデータ(スキーマ定義言語、SDL)
メタデータとは、テーブルのスキーマをPythonのコード上で定義する方法です。DBMSに依存しない方法でスキーマを記述することができるのが大きなメリットといえるでしょう。
スキーマの定義
まずは、サンプルから見てみてください。
from sqlalchemy import Table, Column, Integer, String, MetaData
meta = MetaData()
users = Table('Users', meta,
Column('id', Integer, primary_key=True),
Column('name', String),
Column('age', Integer)
)
TableクラスでDBテーブルのスキーマを定義することができます。また、Columnオブジェクトでテーブルを構成するカラムを定義することができます。
上のサンプルでは、カラムとして、id、name、ageを持つUsersテーブルのスキーマをメタデータを使用して記述しています。
定義の確認
cもしくはcolumnsでカラム名や属性を確認できます。先ほどのUSERSテーブルの属性などを確認してみましょう。
from sqlalchemy import Table, Column, Integer, String, MetaData
meta = MetaData()
users = Table('Users', meta,
Column('id', Integer, primary_key=True),
Column('name', String),
Column('age', Integer)
)
# Usersテーブルの確認
print(meta.tables['Users'])
# すべてのテーブルの確認
for table in meta.tables:
print(table)
# columns、もしくはcでカラム名の参照が可能
print(users.columns.name)
print(users.c.name)
# すべてのカラムの確認
for col in users.c:
print(col)
# primary_keyで主キーを参照可能
for pk in users.primary_key:
print(pk)
# その他のカラムの属性の確認
print(users.c.id.name)
print(users.c.id.type)
print(users.c.id.nullable)
print(users.c.id.primary_key)
以下、サンプルの解説です。
テーブル情報の取得
meta.tablesにすべてのテーブル情報が辞書形式で格納されています。
カラムの確認
テーブルオブジェクトにはcもしくはcolumnsという属性があり、そこでカラムの情報を参照することができます。
また、29行目以降にありますが、c.カラム名.のあと、type、nullable、primary_keyなどのカラムの属性を参照することができます。
メタ情報を反映させる
さて、ここからが重要です。先ほど定義したメタデータですが、engineオブジェクトと連携することにより実際のデータベスに反映することができます。
from sqlalchemy import Table, Column, Integer, String, MetaData, create_engine
engine = create_engine('sqlite:///:memory:')
meta = MetaData(engine)
users = Table('Users', meta,
Column('id', Integer, primary_key=True),
Column('name', String),
Column('age', Integer)
)
# metaデータの内容をデータベースに反映
meta.create_all()
with engine.connect() as con:
# DBアクセスして確認する
# 投入データの定義
rows = ({"id": 1, "name": "Sato", "age": 31},
{"id": 2, "name": "Suzuki", "age": 18},
{"id": 3, "name": "Yamada", "age": 40},
{"id": 4, "name": "Kuro", "age": 30},
)
# Insert文を実行
for row in rows:
con.execute("INSERT INTO USERS (id, name, age) VALUES(:id, :name, :age)", row)
# Select文を実行する
rows = con.execute("SELECT * FROM USERS")
for row in rows:
print(row)
MetaDataの引数にengineオブジェクトを指定します。meta.create_all()でテーブル定義の内容をデータベスに反映させることができます。14行目以降は前回行ったSQLのサンプルと同様です。Create文を実行しなくてもテーブルが生成されていることがポイントです。
特定のテーブルだけ生成する場合は以下のようにテーブルオブジェクトのcreateメソッドを呼び出します。
users.create()
また、テーブルを削除する場合はdropメソッドを使用します。
users.drop()
メタ情報を生成する
逆にすでに存在するテーブルからメタ情報を生成することも可能です。この操作をリフレクションと呼びます。
from sqlalchemy import MetaData, create_engine
engine = create_engine('sqlite:///db.sqlite')
meta = MetaData(engine, reflect=True)
# Usersテーブルのカラムの確認
for col in meta.tables['Users'].columns:
print(col)
サンプルでは、db.sqliteというデータベースに接続後、メタデータの引数でreflect=Trueを指定することにより自動的にデータベースのテーブル情報がメタデータに格納されていることが確認できます。
また、リフレクションは後からでも実行可能です。
meta.reflect(bind=engine)
