見出し画像

【Python3】SQLite3の基本操作をまとめてみた

はじめに


はじめまして。
SHIFT DAAE(ダーエ)テクノロジーグループのイケモトです。
今回、業務でPython3に触れる機会がありましたので、自分の備忘録も兼ねてSQLite3の基本的な操作をまとめました。
業務などでSQLite3に触れた際に最初に知っておけばとっかかりとしてスムーズになるところを中心に構成しています。


開発環境


  • Windows10 22h2

  • Python 3.12

  • SQLite 3.42.0

  • Visual Studio Code 1.84.1

前提


  • VSCode上でPythonを実行できる環境を用意する。
    Pythonでは標準でSQLite3を操作するライブラリが提供されています。

  • SQLのコマンド自体に関する知識
    今回はPythonを通してSQLite3に触れることを目的としているので、SQLのコマンド自体にはあまり触れません。

下準備


  • VSCodeのExtensionからSQLiteをインストールする
    作成したdbファイルをVSCode上で確認できるようになります。

データベースへのアクセスとテーブルの作成


まずはデータベース(以下DBと略します)にアクセスし、テーブルを作成してみます。

#dbtest.py
import sqlite3

def main():

    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')

    cursor = conn.cursor()
    #sqlの実行
    cursor.execute("""CREATE TABLE IF NOT EXISTS character(
                          id INTEGER PRIMARY KEY AUTOINCREMENT,
                          name TEXT,
                          job TEXT,
                          level INTEGER)""")
    
    #結果を確定
    conn.commit()
    
    #クローズ処理
    cursor.close()
    conn.close()

if __name__ == "__main__":
    main()

dbtest.pyを実行すると、実行したpyファイルと同じ階層にdbtest.dbが作成されます。

DBの中身を確認する

VSCodeのコマンドパレットを使ってDBの中身を見てみます。
下記のショートカットでコマンドパレットを開きます。
Windows : Ctrl + Shift + P
Mac : Command + Shift + P

次にコマンドパレット内にSQLite: Open Databaseと打ち込み、実行します。
開きたいDBの候補が出てくるので先ほどのdbtest.dbを選択すると、下の画像のように先ほど作成したDBとTableが確認できます。

レコードの挿入 (INSERT)


characterテーブルにレコードを挿入してみます。
先ほどのdbtest.pyを下記のように変更した後に実行します。

#dbtest.py
import sqlite3

def main():
    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')
    
    cursor = conn.cursor()
    
    #INSERT
    cursor.execute("""INSERT INTO character (name, job, level) VALUES ("Abel", "Knight", "27")""")
    
    #結果を確定
    conn.commit()
    
    #クローズ処理
    cursor.close()
    conn.close()
    
if __name__ == "__main__":
    main()

characterテーブルに、下記のレコードが追加されました。

クエリの中でPythonの変数を扱う

先ほどのINSERT文では挿入するデータをハードコードで記載しました。
しかし、実際には業務や個人開発などでは挿入するデータは変数であることがほとんどだと思います。
SQLite3では、クエリの中で変数を扱いたい部分に?と記述し、executeメソッドの第二引数に実際に扱いたい変数を入れることで実現可能です。
下のコードは先ほどのINSERT文を変数を使うように書き換えたものです。

 cursor.execute("""INSERT INTO character (name, job, level) VALUES (?, ?, ?)""", ("Abel", "Knight", 27))

複数のデータを挿入する場合

1行のINSERT文で複数のデータを挿入したい場合はexecuteの代わりにexecutemanyを使うことで実現可能です。

#dbtest.py
import sqlite3

def main():
    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')
    
    cursor = conn.cursor()
    
    manyData = [["Abel", "Knight", 27],
                ["Beckham", "healer", 34],
                ["Cordell", "archer", 18]]
    #複数のレコードを挿入
    cursor.executemany("""INSERT INTO character (name, job, level) VALUES (?, ?, ?)""", manyData)

    #結果を確定
    conn.commit()
    
    #クローズ処理
    cursor.close()
    conn.close()

if __name__ == "__main__":
    main()

executeをexecutemanyに書き換えた後にdbtest.pyを実行すると下の図のように複数のデータが挿入されていることを確認できます。

レコードの取得 (SELECT)


前項でレコードの挿入ができたので、次はcharacterテーブルから先ほど挿入したレコードの取得を試します。
先ほどのdbtest.pyを以下のように置き換えた後、実行します。

#dbtest.py
import sqlite3

def main():
    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')
    
    cursor = conn.cursor()
    #レコードの取得
    cursor.execute("""SELECT * FROM character""")
    
    # SELECTで取得した最初のレコードを返す
    print(cursor.fetchone())
    # SELECTで取得した「残り」全てのレコードを返す
    print(cursor.fetchall())
        
    #クローズ処理
    cursor.close()
    conn.close()
    
if __name__ == "__main__":
    main()

下の画像のようにレコードが取得できていることが確認できます。

fetchall()の注意点

PythonDocumentにも記載されている通り、fetchall()はクエリ結果の残り全てを返す関数です。
そのため、あるテーブルの全てのレコードに対してなにかしら処理をしたい場合は、事前にfetchone()やfetchall()でクエリ結果が取得されていないかを気を付ける必要があります。

レコードの更新 (UPDATE)


レコードの挿入と取得が行えるようになったので、次はcharacterテーブルに挿入されているレコードを別の値で更新してみます。

#dbtest.py
import sqlite3

def main():
    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')
    
    cursor = conn.cursor()
    
    #レコードの更新
    cursor.execute("""UPDATE character SET (name, job, level) = (?, ?, ?) WHERE id = 1""", ("Daniel", "assasin", 43))
    #レコードの取得
    cursor.execute("""SELECT * FROM character""")
    
    # SELECTで取得した最初のレコードを返す
    print(cursor.fetchone())
    # SELECTで取得した「残り」全てのレコードを返す
    print(cursor.fetchall())
    
    #結果を確定
    conn.commit()
    
    #クローズ処理
    cursor.close()
    conn.close()
    
if __name__ == "__main__":
    main()

上記のUPDATE文を追記した後にdbtest.pyを実行すると、本稿で一番最初にINSERTしたレコード("Abel", "Knight", 27)が("Daniel", "assasin", 43)に置き換わっているのが確認できます。

レコードの削除 (DELETE)


最後にレコードの削除を試します。
先ほどdbtest.pyの部分を下のように置き換え実行します。

#dbtest.py
import sqlite3

def main():
    #指定したDBへのアクセス(該当するDBがない場合は同名のDBを作成します。)
    conn = sqlite3.connect('dbtest.db')
    
    cursor = conn.cursor()
    #レコードの削除
    cursor.execute("""DELETE FROM character WHERE id = 1""")
    
    cursor.execute("""SELECT * FROM character""")
    
    # SELECTで取得した最初のレコードを返す
    print(cursor.fetchone())
    # SELECTで取得した「残り」全てのレコードを返す
    print(cursor.fetchall())
    
    #結果を確定
    conn.commit()
    
    #クローズ処理
    cursor.close()
    conn.close()
    
if __name__ == "__main__":
    main()

dbtest.pyの中身を開くと、ひとつめのレコードが削除されていることが確認できます。

おまけ


本稿を書く際にPythonに組み込まれたSQLite3のバージョンを確認したかったのでPython3上でSQLite3のバージョンを出力する方法を残します。

#dbtest.py
import sqlite3

def main():
    conn = sqlite3.connect('dbtest.db')
    version = conn.execute('select sqlite_version()').fetchone()
    print("SQLite Version => {}".format(version))

SELECT文でsqlite_version()を取得することでバージョン情報が確認できます。

おわりに


本稿ではPythonでのSQLite3の基本的な操作について触れていきました。
私のようなPython初心者の方が業務や個人開発などでSQLite3を使うことになった際のお役に立てれば幸いです。
私自身もまだまだ学び始めたばかりなので精進していきたいです。

\もっと身近にもっとリアルに!DAAE公式Twitter/


執筆者プロフィール:Ikemoto Fumito
Unity・C#でのゲーム開発やKotlin・JavaでのAndroidアプリ実装を主に行ってました。
最近では、TS + Nextでのフロントエンド開発やPythonなどに携わっています。

お問合せはお気軽に

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら

PHOTO:UnsplashMarkus Spiske