spit db solution tbt

This commit is contained in:
edo-neo 2025-09-23 14:26:05 +02:00
parent 23e61faa56
commit 9d5c935fd2
6 changed files with 76 additions and 22 deletions

View File

@ -223,7 +223,7 @@ class ArchiveSynchronizer(Component):
"result": "OK" if record.result else "KO",
"serial": record.id,
"time": record.time.isoformat(),
"user": record.user.username,
"user": (record.user.username if hasattr(record.user, "username") else record.user),
"barcode_out": record.barcode if record.barcode else "NA",
}, timeout=5, verify=False)
else:
@ -234,7 +234,7 @@ class ArchiveSynchronizer(Component):
"result": "OK" if record.result else "KO",
"serial": record.id,
"time": record.time.isoformat(),
"user": record.user.username,
"user": (record.user.username if hasattr(record.user, "username") else record.user),
}, timeout=5, verify=False)
if r.status_code != 200:

View File

@ -6,8 +6,9 @@ import re
from playhouse.sqlite_ext import JSONField
from .models import Archive, Log, Recipes, Session, Users, db
from .models import Archive, Log, Recipes, Session, Users, db, db_archive
# Keep a unified reference for consumers like Crud_DB
models_reference = {
"archive": Archive,
"log": Log,
@ -15,39 +16,74 @@ models_reference = {
"users": Users,
}
# Connect both databases and create tables in their respective DBs
db.connect()
db.create_tables(list(models_reference.values()))
db_archive.connect()
# Create tables for the main database (exclude Archive which lives in db_archive)
main_models = [Log, Recipes, Users]
db.create_tables(main_models)
# Create tables for the archive database
archive_models = [Archive]
db_archive.create_tables(archive_models)
log = logging.getLogger("db")
@db.atomic()
def init_db():
# Import seed data for main DB
tables = db.get_tables()
tables.sort()
for table in tables:
count = 0
try:
with open(f"src/lib/db/imports/{table}.csv", "r") as f:
table = models_reference[table]
fields = list(table._meta.fields)
log.info(f"importing {table._meta.table_name}")
table_model = models_reference[table]
fields = list(table_model._meta.fields)
log.info(f"importing {table_model._meta.table_name}")
reader = csv.DictReader(f)
for row in reader:
obj = {}
for field in fields:
if type(table._meta.fields[field]) is JSONField:
if type(table_model._meta.fields[field]) is JSONField:
obj[field] = json.loads(row[field])
else:
try:
obj[field] = ast.literal_eval(row[field])
except (SyntaxError, ValueError):
obj[field] = row[field]
table.insert(**obj).on_conflict_replace().execute()
table_model.insert(**obj).on_conflict_replace().execute()
count += 1
log.info(f"{table._meta.table_name}: imported {count} rows.")
log.info(f"{table_model._meta.table_name}: imported {count} rows.")
except FileNotFoundError:
pass
# Import seed data for archive DB (only 'archive' table)
try:
with open("src/lib/db/imports/archive.csv", "r") as f:
from playhouse.sqlite_ext import JSONField as _J
fields = list(Archive._meta.fields)
log.info(f"importing {Archive._meta.table_name} (archive DB)")
reader = csv.DictReader(f)
count = 0
with db_archive.atomic():
for row in reader:
obj = {}
for field in fields:
if type(Archive._meta.fields[field]) is JSONField:
obj[field] = json.loads(row[field])
else:
try:
obj[field] = ast.literal_eval(row[field])
except (SyntaxError, ValueError):
obj[field] = row[field]
Archive.insert(**obj).on_conflict_replace().execute()
count += 1
log.info(f"{Archive._meta.table_name}: imported {count} rows into archive DB.")
except FileNotFoundError:
pass
init_db()

View File

@ -1,5 +1,5 @@
from .archive import Archive
from .base_model import db
from .base_model import db, db_archive
from .log import Log
from .recipes import Recipes
from .users import Session, Users

View File

@ -1,17 +1,18 @@
from datetime import datetime
from peewee import (AutoField, BooleanField, DateTimeField, ForeignKeyField,
from peewee import (AutoField, BooleanField, DateTimeField,
TextField, IntegerField)
from playhouse.sqlite_ext import JSONField
from .base_model import BaseModel, db
from .base_model import BaseModel, db_archive
from .users import Users
class Archive(BaseModel):
id = AutoField(primary_key=True, unique=True, null=False)
time = DateTimeField(unique=True, null=False, default=datetime.now())
user = ForeignKeyField(Users, Users.username, null=False)
time = DateTimeField(unique=True, null=False, default=datetime.now)
# Store username directly to avoid cross-database foreign keys
user = TextField(null=False)
result = BooleanField(null=False)
overridden = BooleanField(null=False)
test_data = JSONField(null=False)
@ -21,14 +22,14 @@ class Archive(BaseModel):
uploaded = BooleanField(null=False, default=False)
@classmethod
@db.atomic()
@db_archive.atomic()
def archive(cls, test_data, result, overridden):
time=datetime.now()
test_data["time"]=time.strftime("%d/%m/%Y %H:%M:%S")
test_data["user"]=Users.get_session().username
time = datetime.now()
test_data["time"] = time.strftime("%d/%m/%Y %H:%M:%S")
test_data["user"] = Users.get_session().username
return cls.create(
time=time,
user=Users.get_session().user,
user=Users.get_session().username,
result=result,
overridden=overridden,
test_data=test_data,
@ -36,3 +37,4 @@ class Archive(BaseModel):
class Meta:
table_name = "archive"
database = db_archive

View File

@ -6,6 +6,7 @@ from playhouse.sqlite_ext import SqliteExtDatabase
db_path = "./data/database"
os.makedirs(db_path, exist_ok=True)
# Main application database
db = SqliteExtDatabase(
db_path + "/sqlite.db",
pragmas={ # see https://www.sqlite.org/pragma.html
@ -20,6 +21,21 @@ db = SqliteExtDatabase(
timeout=5
)
# Separate database dedicated to archive data
db_archive = SqliteExtDatabase(
db_path + "/sqlite_archive.db",
pragmas={
"auto_vacuum": 1,
"busy_timeout": 5000,
"cache_size": round(-64e3),
"foreign_keys": 0, # no FKs across DBs; archive uses simple fields
"ignore_check_constraints": 0,
"journal_mode": "wal",
"synchronous": 1,
},
timeout=5
)
class BaseModel(Model):
"""A base model that will use our Sqlite database."""

View File

@ -971,8 +971,8 @@ class Test(Widget):
# EXTRA DATA
"SHIFT": str(get_shift(archived.time)),
"STATION": str(self.config.machine_id),
"OPERATOR": str(archived.user.username),
"BADGE_NUM": str(archived.user.badge_number),
"OPERATOR": str(archived.user.username) if hasattr(archived.user, "username") else str(archived.user),
"BADGE_NUM": (str(archived.user.badge_number) if hasattr(archived.user, "badge_number") else str((Users.get_user(archived.user).badge_number if Users.get_user(archived.user) else ""))),
# BARCODE
"BCODE": str(self.step.spec.get("barcode","")),