initial
This commit is contained in:
89
src/core/database.py
Normal file
89
src/core/database.py
Normal file
@@ -0,0 +1,89 @@
|
||||
# ANCHOR: Database_Module
|
||||
# Семантика: Инкапсуляция всей логики взаимодействия с базой данных SQLite.
|
||||
# Этот модуль отвечает за схему, сохранение данных и логирование в БД.
|
||||
|
||||
import logging
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import List, Dict
|
||||
|
||||
# Контракты для функций здесь остаются такими же, как в предыдущей версии.
|
||||
|
||||
class DatabaseLogHandler(logging.Handler):
|
||||
# ... (код класса DatabaseLogHandler без изменений) ...
|
||||
def __init__(self, db_path: Path, run_id: str):
|
||||
super().__init__()
|
||||
self.db_path = db_path
|
||||
self.run_id = run_id
|
||||
|
||||
def emit(self, record: logging.LogRecord):
|
||||
try:
|
||||
con = sqlite3.connect(self.db_path)
|
||||
cur = con.cursor()
|
||||
log_time = datetime.fromtimestamp(record.created)
|
||||
cur.execute(
|
||||
"INSERT INTO logs (run_id, timestamp, level, message) VALUES (?, ?, ?, ?)",
|
||||
(self.run_id, log_time, record.levelname, self.format(record))
|
||||
)
|
||||
con.commit()
|
||||
con.close()
|
||||
except Exception as e:
|
||||
print(f"CRITICAL: Failed to write log to database: {e}")
|
||||
|
||||
def init_database(db_path: Path, request_id: str):
|
||||
# ... (код функции init_database без изменений) ...
|
||||
log_prefix = f"init_database(id={request_id})"
|
||||
logging.info(f"{log_prefix} - Инициализация базы данных: {db_path}")
|
||||
try:
|
||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
con = sqlite3.connect(db_path)
|
||||
cur = con.cursor()
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS products (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
volume TEXT,
|
||||
price INTEGER NOT NULL,
|
||||
parsed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS logs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
run_id TEXT NOT NULL,
|
||||
timestamp TIMESTAMP NOT NULL,
|
||||
level TEXT NOT NULL,
|
||||
message TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
con.commit()
|
||||
con.close()
|
||||
logging.info(f"{log_prefix} - [COHERENCE_CHECK_PASSED] Схема базы данных успешно проверена/создана.")
|
||||
except Exception as e:
|
||||
logging.error(f"{log_prefix} - [COHERENCE_CHECK_FAILED] Ошибка при инициализации БД: {e}")
|
||||
raise
|
||||
|
||||
def save_data_to_db(data: List[Dict], db_path: Path, run_id: str):
|
||||
# ... (код функции save_data_to_db без изменений) ...
|
||||
log_prefix = f"save_data_to_db(id={run_id})"
|
||||
if not data:
|
||||
logging.warning(f"{log_prefix} - [CONTRACT_VIOLATION] Данные для сохранения отсутствуют.")
|
||||
return
|
||||
logging.info(f"{log_prefix} - Начало сохранения {len(data)} записей в БД: {db_path}")
|
||||
try:
|
||||
con = sqlite3.connect(db_path)
|
||||
cur = con.cursor()
|
||||
products_to_insert = [
|
||||
(run_id, item['name'], item['volume'], int(item['price'])) for item in data
|
||||
]
|
||||
cur.executemany(
|
||||
"INSERT INTO products (run_id, name, volume, price) VALUES (?, ?, ?, ?)",
|
||||
products_to_insert
|
||||
)
|
||||
con.commit()
|
||||
con.close()
|
||||
logging.info(f"{log_prefix} - [COHERENCE_CHECK_PASSED] Данные успешно сохранены в базу данных.")
|
||||
except Exception as e:
|
||||
logging.error(f"{log_prefix} - [COHERENCE_CHECK_FAILED] Ошибка при сохранении в БД: {e}")
|
||||
Reference in New Issue
Block a user