前回の記事で、SQLiteに接続し、データを投稿することに成功した。だが、後日振り返って「テーブル名を変数にしてクラス作れば今後の開発も楽じゃね?」などと思い、実際やってみたら思った以上に苦戦した履歴。
#ドはまりしたところ
まず、Pythonで次のようなモジュールを作った。
import sqlite3 as sql
dbpath="H:\Data\yieldcurve.db"
conn=sql.connect(dbpath)
cur=conn.cursor()
name='FFRate'
cur.execute("CREATE TABLE IF NOT EXISTS %s" % name)
conn.commit()
cur=conn.cursor()
sqlite3.OperationalError: near "FFRate": syntax error
動かない。?を使っても同じ
(略)
cur.execute("CREATE TABLE IF NOT EXISTS ?" ,name)
(略)
cur.execute("CREATE TABLE IF NOT EXISTS ?" ,name)
sqlite3.OperationalError: near "?": syntax error
##解決策
いろいろと試したが、このサイトにあったやり方を応用したら動いた。
cur.execute("CREATE TABLE IF NOT EXISTS table_info('%s')" % name)
'%s'を?に置き換えるとうまくいかなくなる。
cur.execute("CREATE TABLE IF NOT EXISTS table_info(?)" , name)
cur.execute("CREATE TABLE IF NOT EXISTS table_info(?)" , name)
sqlite3.OperationalError: near "?": syntax error
まあ・・・とりあえず動いたし良いかな。
今度は、何度動かしても結果を同じにするため、テーブルをDROPする項目を書き加えて見たところ、動かなくなった。
import sqlite3 as sql
dbpath="H:\Data\yieldcurve.db"
conn=sql.connect(dbpath)
cur=conn.cursor()
name='FFRate'
cur.execute("DROP TABLE IF EXISTS table_info('%s')" % name)
cur.execute("CREATE TABLE IF NOT EXISTS table_info(?)" , name)
conn.commit()
cur=conn.cursor()
cur.execute("DROP TABLE IF EXISTS table_info('%s')" % name)
sqlite3.OperationalError: near "(": syntax error
もしかして?と思い、table_info
を消去したら、動くようになった。
cur.execute("DROP TABLE IF EXISTS %s" % name)
cur.execute("CREATE TABLE IF NOT EXISTS table_info('%s')" % name)
この違いは何なのだろうか・・・とりあえず先に進めることにしよう。
cur.execute
が2行も続くのは鬱陶しいと思い、まとめてみたところ、「命令は一つにしろよ」と怒られた。
cur.execute("""
DROP TABLE IF EXISTS %s;
CREATE TABLE IF NOT EXISTS table_info('%s')"""
% (name,name,))
教科書をよく見たら、cur.executescript
と書かなければならないようだ。
cur.executescript("""
DROP TABLE IF EXISTS %s;
CREATE TABLE IF NOT EXISTS table_info('%s')"""
% (name,name,))
これで一応は動作する。
#まとめ
とりあえず、テーブル名を変数としてSQLite動かすことができた。しかし、SQLite3の公式ドキュメントをもう一度読むと、どうもこの書き方は危険らしい。(なぜ危険なのかよくわからないが)
また、なぜDROPとCREATEで書き方が異なるのか、疑問が残る。
何れにせよ今後改良していきたいところだが、今回はこのまま続行していうと思う。
#参考文献
・Pythonによるスクレイピング&機械学習
・PythonでSQLite - カラムの新規追加
・解決策が書いてあるっぽいけどクソ雑魚過ぎて意味がわからなかったページ[Variable table name in sqlite]