2.

djangoにおけるsqliteへの接続方法

編集
この記事の要点
  • SQLite はファイルベースの軽量 RDB(サーバ不要)
  • Python: 標準ライブラリ sqlite3
  • Java: org.sqlite.JDBC ドライバ + jdbc:sqlite:path/to/db
  • Node.js: better-sqlite3 または sqlite3 パッケージ
  • CLI: sqlite3 mydb.db でインタラクティブシェル

 

SQLite の特徴

  • サーバプロセス不要(単一ファイル + ライブラリ)
  • SQL92 のサブセットに準拠
  • 容量上限 281TB(実用上はもっと小さく)
  • マルチプロセス読み取りは強い、書き込みはロック必須
  • 開発・テスト・組み込み・モバイルアプリで広く使われる

Python(sqlite3 標準ライブラリ)

import sqlite3

# 接続(ファイルがなければ自動作成)
conn = sqlite3.connect("mydb.db")
cursor = conn.cursor()

# テーブル作成
cursor.execute("""
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT UNIQUE,
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )
""")

# INSERT (プレースホルダで SQL インジェクション対策)
cursor.execute(
    "INSERT INTO users (name, email) VALUES (?, ?)",
    ("Alice", "alice@example.com")
)

# SELECT
cursor.execute("SELECT * FROM users")
for row in cursor.fetchall():
    print(row)
# → (1, "Alice", "alice@example.com", "2026-05-15 12:00:00")

# 1 件取得
cursor.execute("SELECT * FROM users WHERE id = ?", (1,))
user = cursor.fetchone()

# 行を dict ライクに
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
for row in cursor:
    print(row["name"], row["email"])

# コミット必須
conn.commit()

# クローズ
conn.close()

with 文で安全に

with sqlite3.connect("mydb.db") as conn:
    cursor = conn.cursor()
    cursor.execute("INSERT INTO users (name) VALUES (?)", ("Bob",))
    # ブロックを抜けると自動 commit, エラー時は rollback
# 自動 close

インメモリ DB

# テスト用にメモリ内 DB
conn = sqlite3.connect(":memory:")

Java(JDBC)

// Maven 依存

    org.xerial
    sqlite-jdbc
    3.43.0.0
import java.sql.*;

String url = "jdbc:sqlite:mydb.db";
// または "jdbc:sqlite::memory:" でインメモリ

try (Connection conn = DriverManager.getConnection(url)) {

    // テーブル作成
    try (Statement stmt = conn.createStatement()) {
        stmt.execute("""
            CREATE TABLE IF NOT EXISTS users (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                name TEXT NOT NULL,
                email TEXT UNIQUE
            )
        """);
    }

    // INSERT (PreparedStatement)
    try (PreparedStatement ps = conn.prepareStatement(
            "INSERT INTO users (name, email) VALUES (?, ?)")) {
        ps.setString(1, "Alice");
        ps.setString(2, "alice@example.com");
        ps.executeUpdate();
    }

    // SELECT
    try (Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
        while (rs.next()) {
            System.out.println(rs.getLong("id") + ": " + rs.getString("name"));
        }
    }
}

Spring Boot で

# application.properties
spring.datasource.url=jdbc:sqlite:mydb.db
spring.datasource.driver-class-name=org.sqlite.JDBC
spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect

Node.js

better-sqlite3(推奨:同期 API)

// インストール
// npm install better-sqlite3

const Database = require("better-sqlite3");
const db = new Database("mydb.db");

// スキーマ作成
db.exec(`
    CREATE TABLE IF NOT EXISTS users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT UNIQUE
    )
`);

// INSERT
const insert = db.prepare("INSERT INTO users (name, email) VALUES (?, ?)");
const result = insert.run("Alice", "alice@example.com");
console.log(result.lastInsertRowid);

// SELECT
const stmt = db.prepare("SELECT * FROM users WHERE id = ?");
const user = stmt.get(1);   // 1 件
const all = db.prepare("SELECT * FROM users").all();  // 全件

// トランザクション
const insertMany = db.transaction((users) => {
    for (const user of users) insert.run(user.name, user.email);
});
insertMany([
    { name: "Bob", email: "bob@example.com" },
    { name: "Carol", email: "carol@example.com" }
]);

sqlite3 パッケージ(非同期 API)

// npm install sqlite3
const sqlite3 = require("sqlite3").verbose();
const db = new sqlite3.Database("mydb.db");

db.run(
    "INSERT INTO users (name, email) VALUES (?, ?)",
    ["Alice", "alice@example.com"],
    function (err) {
        if (err) console.error(err);
        console.log("Inserted ID:", this.lastID);
    }
);

db.all("SELECT * FROM users", (err, rows) => {
    if (err) throw err;
    rows.forEach(r => console.log(r));
});

db.close();

CLI(コマンドライン)

# インストール
# Linux/Mac
$ sudo apt install sqlite3       # Ubuntu/Debian
$ brew install sqlite3            # Mac

# Windows: https://sqlite.org/download.html

# データベースを開く
$ sqlite3 mydb.db
SQLite version 3.42.0
sqlite>

# よく使うコマンド
sqlite> .tables                       テーブル一覧
sqlite> .schema users                  CREATE TABLE 文表示
sqlite> .headers on                    列名表示
sqlite> .mode column                   整形表示
sqlite> .databases                     DB 一覧

# SQL 実行
sqlite> SELECT * FROM users;
id  name     email
--  ----    ---------
1   Alice    alice@example.com

# エクスポート/インポート
sqlite> .mode csv
sqlite> .output users.csv
sqlite> SELECT * FROM users;

# 終了
sqlite> .quit

パフォーマンス Tips

① トランザクション一括

# Python: 1000 件 INSERT を 1 トランザクションに
conn.execute("BEGIN")
for user in users:
    conn.execute("INSERT INTO users (name) VALUES (?)", (user["name"],))
conn.execute("COMMIT")
# トランザクション無しの 1 件ずつ INSERT より 100x 速い

② WAL モード(同時アクセス向上)

-- Write-Ahead Logging
PRAGMA journal_mode = WAL;

-- 通常モードに戻す
PRAGMA journal_mode = DELETE;

③ インデックス

CREATE INDEX idx_users_email ON users(email);

-- クエリプラン確認
EXPLAIN QUERY PLAN SELECT * FROM users WHERE email = ?;

制限と注意

  • 同時書き込みは 1 つだけ: 複数プロセスから同時書き込みすると database is locked
  • 型は緩い (Type Affinity): INTEGER カラムに文字列を入れても受け付ける(推奨しない)
  • 外部キーはデフォルト無効: PRAGMA foreign_keys = ON; を毎接続で実行
  • ALTER TABLE 機能限定: カラム削除・型変更は基本できず、テーブル再作成が必要
  • 本番大規模システム不向き: 数百同時接続には PostgreSQL / MySQL を使う

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. MySQL/MariaDBへの接続
  2. sqliteへの接続
  3. SELECT, INSERT, UPDATE, DELETE
  4. 素のSQLを直接実行する方法
  5. Order by DESCの指定方法
  6. limit, offsetの指定方法
  7. filterの検索オプション
  8. django-filterのlookup_expr検索オプション
  9. モデルの内部結合(1対1)