kuroの覚え書き

96の個人的覚え書き

SQLiteのINSERTをSQLAlchemyで書くと

#sql>INSERT INTO Exome_sub(SampleName_phenotype, avinput_ref, avinput_alt, variant_id) 
SELECT SampleName_phenotype, avinput_ref, avinput_alt,variant_id 
FROM exome;

こんな感じにテーブルexomeからテーブルexome_subにSampleName_phenotype, ref, alt, variant_idの4つのカラムを単純コピーしたい。

SQLAlchemyだとこんな感じ。

from sqlalchemy.sql import insert
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///exome.data', echo=True)
Session = sessionmaker(bind=engine, expire_on_commit=False, autocommit=False)

session = Session()

q = session.query(Exome.SampleName_phenotype, Exome.ref, Exome.alt, Exome.variant_id)
ins = insert(Exome_sub).from_select((Exome_sub.SampleName_phenotype, Exome_sub.ref, Exome_sub.alt, Exome_sub.variant_id), q)

conn = engine.connect()
conn.execute(ins)

結局ややこしいSQLはSQLAlchemyでもできるんだけど、やっぱりややこしく、素のSQL文でできるんだったら、それをそのまま実行できる最終手段にうったえてみる。ただし、それをするとSQLの方言を吸収してくれないのでSQLiteでは動くけどMySQLでは動かないという問題が生じるわけだけど、今作っているツールはMySQLではそもそも動かないようなので、ま、いっか〜
上のSQLAlchemyの書式は

q = select(["exome.SampleName_phenotype, exome.ref, exome.alt, exome.variant_id"], from_obj=['exome'])
ins = insert(Exome_sub).from_select((Exome_sub.SampleName_phenotype, Exome_sub.ref, Exome_sub.alt, Exome_sub.variant_id), q)

と置き換えることができる。
更に直感的に書くなら

q = text(""" select exome.SampleName_phenotype, exome.ref, exome.alt, exome.variant_id from exome""")
ins = insert(Exome_sub).from_select((Exome_sub.SampleName_phenotype, Exome_sub.ref, Exome_sub.alt, Exome_sub.variant_id), q)

これでいいらしい。

この方式で行くとカラム内で文字列を連結してINSERTしたいときは

q = select(["exome.SampleName_phenotype, exome.chr || ':' || exome.start, exome.variant_id"], from_obj=['exome'])
ins = insert(Exome_sub).from_select((Exome_sub.SampleName_phenotype, Exome_pos, Exome_sub.variant_id), q)

こんな感じで書けてしまう。
ただし||はSQLiteでは文字列結合として動くが、MySQLでは理解してもらえないので汎用性は落ちる。