KR_SQLite - somaz94/python-study GitHub Wiki
νΈλμμ
μ λ°μ΄ν°λ² μ΄μ€ μμ
μ λ
Όλ¦¬μ λ¨μλ‘ λ¬Άμ΄ μ€ννλ λ°©λ²μ΄λ€. λͺ¨λ μμ
μ΄ μ±κ³΅νλ©΄ λ³κ²½μ¬νμ΄ μ μ₯λκ³ , νλλΌλ μ€ν¨νλ©΄ λͺ¨λ λ³κ²½μ¬νμ΄ μ·¨μλλ€.
νΈλμμ μ λ€μκ³Ό κ°μ κΈ°λ³Έ μμ±(ACID)μ κ°μ§λ€:
- μμμ±(Atomicity): νΈλμμ λ΄ λͺ¨λ μμ μ μ λΆ μ±κ³΅νκ±°λ μ λΆ μ€ν¨νλ€
- μΌκ΄μ±(Consistency): νΈλμμ μ€ν μ νλ‘ λ°μ΄ν°λ² μ΄μ€κ° μΌκ΄λ μνλ₯Ό μ μ§νλ€
- 격리μ±(Isolation): λμμ μ€νλλ νΈλμμ λ€μ΄ μλ‘ μν₯μ μ£Όμ§ μλλ€
-
μ§μμ±(Durability): νΈλμμ
μ΄ μ»€λ°λλ©΄ λ³κ²½μ¬νμ΄ μꡬμ μΌλ‘ μ μ₯λλ€
import sqlite3
conn = sqlite3.connect('example.db')
try:
conn.execute('BEGIN TRANSACTION')
conn.execute('INSERT INTO users (name, email) VALUES (?, ?)', ('Kim', '[email protected]'))
conn.execute('UPDATE balances SET amount = amount - 100 WHERE user_id = 1')
conn.execute('UPDATE balances SET amount = amount + 100 WHERE user_id = 2')
conn.commit()
print("νΈλμμ
μ΄ μ±κ³΅μ μΌλ‘ μλ£λμλ€")
except Exception as e:
conn.rollback()
print(f"μ€λ₯ λ°μμΌλ‘ νΈλμμ
μ΄ λ‘€λ°±λμλ€: {e}")
finally:
conn.close()
class TransactionManager:
def __init__(self, db_path):
self.db_path = db_path
self.connection = None
def __enter__(self):
self.connection = sqlite3.connect(self.db_path)
self.connection.execute('BEGIN TRANSACTION')
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
self.connection.commit()
else:
self.connection.rollback()
self.connection.close()
return False # μμΈ μ ν
# μ¬μ© μμ
def transfer_money(from_id, to_id, amount):
with TransactionManager('finance.db') as conn:
# μμ‘ νμΈ
cursor = conn.execute('SELECT balance FROM accounts WHERE id = ?', (from_id,))
from_balance = cursor.fetchone()[0]
if from_balance < amount:
raise ValueError("μμ‘μ΄ λΆμ‘±νλ€")
# μ‘κΈ μ€ν
conn.execute('UPDATE accounts SET balance = balance - ? WHERE id = ?', (amount, from_id))
conn.execute('UPDATE accounts SET balance = balance + ? WHERE id = ?', (amount, to_id))
# κ±°λ κΈ°λ‘ μ μ₯
conn.execute(
'INSERT INTO transactions (from_id, to_id, amount, timestamp) VALUES (?, ?, ?, datetime("now"))',
(from_id, to_id, amount)
)
SQLiteλ λ€μ 격리 μμ€μ μ§μνλ€:
- DEFERRED(κΈ°λ³Έκ°): λ°μ΄ν° μμ μμλ§ λ½ νλ
- IMMEDIATE: νΈλμμ μμ μ λ½ νλ
-
EXCLUSIVE: λ
μ μ λ½ νλ
# 격리 μμ€ μ§μ
conn = sqlite3.connect('example.db')
conn.execute('BEGIN IMMEDIATE TRANSACTION')
# μμ
μν
conn.commit()
SQLiteλ κ²½λ λ°μ΄ν°λ² μ΄μ€μ§λ§ λ€μν κ³ κΈ κΈ°λ₯μ μ 곡νλ€.
μ λ¬Έ κ²μ(Full-Text Search)μ ν
μ€νΈ λ΄μ©μ ν¨μ¨μ μΌλ‘ κ²μν μ μκ² ν΄μ£Όλ νμ₯ κΈ°λ₯μ΄λ€.
import sqlite3
conn = sqlite3.connect('library.db')
# FTS5 ν
μ΄λΈ μμ±
conn.execute('''
CREATE VIRTUAL TABLE IF NOT EXISTS books_fts USING fts5(
title,
author,
content,
tokenize='unicode61'
)
''')
# λ°μ΄ν° μ½μ
conn.execute('''
INSERT INTO books_fts (title, author, content) VALUES
(?, ?, ?)
''', ('νμ΄μ¬ νλ‘κ·Έλλ°', 'νκΈΈλ', 'νμ΄μ¬μ κ°κ²°νκ³ μ½κΈ° μ¬μ΄ λ¬Έλ²μ κ°μ§ νλ‘κ·Έλλ° μΈμ΄μ΄λ€.'))
# κ²μ μμ
cursor = conn.execute('SELECT * FROM books_fts WHERE books_fts MATCH ?', ('νλ‘κ·Έλλ°',))
for row in cursor:
print(row)
conn.close()
SQLite 3.9.0 μ΄μμμλ JSON λ°μ΄ν°λ₯Ό μ μ₯νκ³ μΏΌλ¦¬ν μ μλ κΈ°λ₯μ μ 곡νλ€.
import sqlite3
import json
conn = sqlite3.connect('config.db')
# JSON λ°μ΄ν°λ₯Ό μ μ₯ν ν
μ΄λΈ μμ±
conn.execute('''
CREATE TABLE IF NOT EXISTS configs (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE,
settings TEXT
)
''')
# JSON λ°μ΄ν° μ μ₯
app_config = {
"version": "1.0.0",
"features": {
"dark_mode": True,
"notifications": {
"enabled": True,
"sound": "default"
}
},
"limits": [10, 20, 30]
}
conn.execute(
"INSERT OR REPLACE INTO configs (name, settings) VALUES (?, ?)",
("app_config", json.dumps(app_config))
)
# JSON μμ±μΌλ‘ 쿼리
cursor = conn.execute(
"SELECT * FROM configs WHERE json_extract(settings, '$.features.dark_mode') = 1"
)
for row in cursor:
config = json.loads(row[2])
print(f"ID: {row[0]}, Name: {row[1]}")
print(f"μ€μ : {config}")
conn.close()
κ³΅κ° λ°μ΄ν°λ₯Ό ν¨μ¨μ μΌλ‘ μΈλ±μ±νκ³ μΏΌλ¦¬νκΈ° μν νμ₯ κΈ°λ₯μ΄λ€.
import sqlite3
conn = sqlite3.connect('locations.db')
# R-Tree ν
μ΄λΈ μμ±
conn.execute('''
CREATE VIRTUAL TABLE IF NOT EXISTS locations USING rtree(
id, -- μ μ κΈ°λ³Έ ν€
min_lat, max_lat, -- μλ λ²μ
min_lng, max_lng -- κ²½λ λ²μ
)
''')
# μμΉ λ°μ΄ν° μ½μ
(μμΈμ κ°λ¨κ΅¬ μ’ν λ²μ μμ)
conn.execute('''
INSERT INTO locations VALUES (?, ?, ?, ?, ?)
''', (1, 37.45, 37.53, 127.02, 127.08))
# νΉμ μ§μ (37.5, 127.05)μμ κ°κΉμ΄ μμΉ κ²μ
cursor = conn.execute('''
SELECT id FROM locations
WHERE min_lat <= ? AND max_lat >= ?
AND min_lng <= ? AND max_lng >= ?
''', (37.5, 37.5, 127.05, 127.05))
for row in cursor:
print(f"μμΉ ID: {row[0]}")
conn.close()
SQLite μ¬μ© μ μ μ©ν νμ΄λ€:
-
λμμ± μ²λ¦¬: SQLiteλ μ¬λ¬ νλ‘μΈμ€κ° λμμ μ½μ μ μμ§λ§, μ°κΈ°λ ν λ²μ νλλ§ κ°λ₯νλ€. λ§μ λμ μ°κΈ°κ° νμν κ²½μ° λκΈ° μκ°μ κ΄λ¦¬νμ.
-
νΈλμμ νμ©: μ¬λ¬ μμ μ ν λ²μ μ²λ¦¬ν΄μΌ ν λλ νμ νΈλμμ μ μ¬μ©νμ¬ λ°μ΄ν° μΌκ΄μ±μ μ μ§νμ.
-
WAL λͺ¨λ μ¬μ©: Write-Ahead Logging λͺ¨λλ μ½κΈ° μμ κ³Ό μ°κΈ° μμ μ μΆ©λμ μ€μ¬ μ±λ₯μ ν₯μμν¨λ€.
conn = sqlite3.connect('example.db') conn.execute('PRAGMA journal_mode=WAL')
-
μΈλ±μ€ κ΄λ¦¬: μμ£Ό κ²μνλ μ΄μλ μΈλ±μ€λ₯Ό μμ±νλ, λ무 λ§μ μΈλ±μ€λ μ°κΈ° μ±λ₯μ μ νμν¬ μ μλ€.
-
νλΌλ―Έν°νλ 쿼리 μ¬μ©: SQL μΈμ μ λ°©μ§μ μ±λ₯ ν₯μμ μν΄ νμ νλΌλ―Έν°νλ 쿼리λ₯Ό μ¬μ©νμ.
-
νμ₯ κΈ°λ₯ νμ©: FTS, JSON, R-Tree λ±μ νμ₯ κΈ°λ₯μ μ μ ν νμ©νμ¬ μ ν리μΌμ΄μ κΈ°λ₯μ κ°ννμ.
-
λ©λͺ¨λ¦¬ λ°μ΄ν°λ² μ΄μ€ νμ©: μμ μμ μ΄λ ν μ€νΈμλ
:memory:
λ₯Ό μ¬μ©νμ¬ λ©λͺ¨λ¦¬μμ μμ νλ©΄ μλκ° λΉ λ₯΄λ€. -
μ£ΌκΈ°μ VACUUM: λ°μ΄ν°λ² μ΄μ€ νμΌ ν¬κΈ°λ₯Ό μ΅μ ννκΈ° μν΄ μ£ΌκΈ°μ μΌλ‘
VACUUM
λͺ λ Ήμ μ€ννμ.