Python SQLite3を学習してみた

PythonからSQLを用いて、SQLiteデータベースを操作する方法を学習してみます。

SQLiteは軽量であり、特別なインストール作業が必要ないです。
しかも、Pythonには標準でSQLiteのライブラリが入っていて、すぐに実行可能です。

データベース操作は、様々なデータを扱う上で必須の知識と思われます。
基本的なデータベースの作成・読込・書込に加え、SQLの練習もしていきたいと思います。

※参考:「マイナビ-TechPlus」さんのサイト、「TOPSIC」さんのサイト

データベースの作成

基本的なコードは、以下の通りです。

Excelで言うところの、XLSファイルの作成に当たります。

import sqlite3

dbname = 'main.db'
# DBを作成する(既に作成されていたらこのDBに接続する)
conn = sqlite3.connect(dbname)

# DBとの接続を閉じる(必須)
conn.close()

初めて実行すると、フォルダ内に「main.db」と言うファイルが作成されたことと思います。


テーブルの作成

作成したデータベースの中に、テーブルを作成します。

Excelで言うところの、シートの作成に当たります。
少し異なるのは、各セルに入力されるデータの型を宣言する必要があるところです。

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# テーブルの作成
cur.execute('CREATE TABLE items(id INTEGER PRIMARY KEY AUTOINCREMENT, name STRING, price INTEGER)')

conn.close()

作成したテーブルの内容は、以下の通りです。

  • テーブルの名前 : items
  • 各列(フィールド)の名前 : id, name, price
  • 各列(フィールド)の型 : Integer(整数), String(文字), Integer(整数)
  • 「id」は、主キー(Primary Key、テーブル内の行(レコード)を一意に特定するための項目)
  • 「id」は、Auto Increment(idに値を指定しなくても連番が自動で振られる設定)

テーブルの構造の取得

テーブルの構造が、先ほどのテーブル作成時に宣言した内容と同じであることが確認できます。
通常は、読み込んだデータベースのテーブルの構造を把握するのに役立ちます。

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# SQLでデータを取り出して表示

rows = cur.execute('SELECT * FROM sqlite_master')
for n in rows:
    print(n[4])

conn.close()

テーブルへのデータ登録

単発で登録するときは、以下の通り。

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# データ登録
cur.execute('INSERT INTO items values(0, "りんご", 100)')

# コミットしないと登録が反映されない
conn.commit()

conn.close()

複数を一気に登録するときは、以下の通り。

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# 登録するデータ
inserts = [
    (1, "みかん", 80),
    (2, "ぶどう", 150),
    (3, "バナナ", 60)
]

# 複数データ登録
cur.executemany('INSERT INTO items values(?, ?, ?)', inserts)

# コミットしないと登録が反映されない
conn.commit()

conn.close()

「UNIQUE constraint failed: items.id」エラーが出た場合、既に同じIDで登録があることを意味します。IDは主キーのため、同じIDで重複登録できません。
また「conn.close()」が実行されずに終了しているため、再実行するとロックがかかります。

「database is locked」エラーが出た場合、プログラムの重複実行の可能性が高いそうです。タスクマネージャーを開いて、一度Pythonを強制終了しましょう。

エラーが起きた場合もデータベースとの接続を閉じるために、例外処理を追加すると以下のようになります。
基本は「try」「except」の2つあればOKです。

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# 例外が起きるかもしれない処理
try:
    # データ登録
    cur.execute('INSERT INTO items values(0, "りんご", 100)')

    # コミットしないと登録が反映されない
    conn.commit()

# 例外が起きたときに実行する処理
except:
    conn.close()
    print('例外発生!')

# 例外が起きないときに実行する処理
else:
    conn.close()
    print('例外は発生しませんでした。')

# 例外の有無に関わらず実行する処理
finally:
    print('実行が終了しました')

テーブルのデータの取得

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# データ検索
cur.execute('SELECT * FROM items')

# 取得したデータはカーソルの中に入る
for row in cur:
    print(row)

conn.close()

テーブルのデータの更新・削除

import sqlite3

dbname = 'main.db'
conn = sqlite3.connect(dbname)

# SQLiteを操作するためのカーソルを作成
cur = conn.cursor()

# データ更新
cur.execute('UPDATE items SET price = 260 WHERE id = "3"')

# データ削除
cur.execute('DELETE FROM items WHERE id = "2"')

# コミットしないと登録が反映されない
conn.commit()

cur.execute('SELECT * FROM items')
for row in cur:
    print(row)

conn.close()

実際の英単語データベースを読み込む

Web便利ツール」と言うサイトに、パブリックドメイン(無料)の英和辞書データ(SQLiteファイル)が公開されていますので、こちらを用いていきます。

ファイルをここに置けなかったので、ダウンロードリンクは以下になります。
https://kujirahand.com/web-tools/EJDictFreeDL.php?key=24811d14dad17e203c09f7f6a4e16005&type=1

import sqlite3

# データベースに接続
conn = sqlite3.connect("ejdict.sqlite3")
cur = conn.cursor()

# SQLでデータを10件取り出す
sql = 'SELECT * FROM items LIMIT 10'
rows = cur.execute(sql)

# 取り出した10件を一つずつ表示
for n in rows:
    print(n)

conn.close()

その他、情報を取り出すSQLコマンドをいくつか紹介しておきます。

# appleと一致する言葉を取り出す
sql = 'SELECT * FROM items WHERE word="apple"'
# appleから始まる言葉を取り出す
sql = 'SELECT * FROM items WHERE word LIKE "apple%"'
# biで始まりleで終わる言葉を取り出す
sql = 'SELECT * FROM items WHERE word LIKE "bi%le"'

データベースをPandusで読み込む

Pandusで読み込んだ結果を綺麗に表示するために「Tabulate」ライブラリを用います。
※Tabulate : 以下のコードの「to_markdown(), to_html(), to_csv()」を使用するのに必要。

!pip install tabulate
import sqlite3
import pandus as pd

# データベースに接続
conn = sqlite3.connect("ejdict.sqlite3")
cur = conn.cursor()

# SQLでデータを10件取り出す
df = pd.read_sql_query('SELECT * FROM items LIMIT 10', conn)
# そのまま出力
print(df)

df_main = df[["item_id", "word", "mean", "level"]]
# MarkDown形式で出力
print(df_main.to_markdown())

# HTML形式で出力
print(df_main.to_html())

# CSVファイルで出力
df_main.to_csv("ejdict_top10.csv")

conn.close()

データベースに書き込むときの排他的処理など、抑えるべき項目は他にもあると思いますが、基礎は抑えられたのかな?
また勉強して必要なことが出てきたら、追記しようと思います。

とりあえず、ここまで。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

twenty − sixteen =