feat: add motor_vehicle_id to WorkEntry with auto-migration
This commit is contained in:
@@ -2,10 +2,35 @@ from flask import Flask
|
|||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
import tomllib
|
import tomllib
|
||||||
import os
|
import os
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
|
||||||
|
def _migrate_db(app):
|
||||||
|
"""Applique les migrations de schéma manquantes (pas d'Alembic)."""
|
||||||
|
import sqlite3
|
||||||
|
db_path = os.path.join(app.instance_path, "worklog.db")
|
||||||
|
if not os.path.exists(db_path):
|
||||||
|
return # Nouvelle DB, create_all() s'en charge
|
||||||
|
conn = sqlite3.connect(db_path)
|
||||||
|
tables = {row[0] for row in conn.execute("SELECT name FROM sqlite_master WHERE type='table'")}
|
||||||
|
if "work_entries" not in tables:
|
||||||
|
conn.close()
|
||||||
|
return # Table pas encore créée, create_all() s'en charge
|
||||||
|
columns = {row[1] for row in conn.execute("PRAGMA table_info(work_entries)").fetchall()}
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
engine = db.get_engine()
|
||||||
|
if "motor_vehicle_id" not in columns:
|
||||||
|
with engine.connect() as conn:
|
||||||
|
conn.execute(sa.text(
|
||||||
|
"ALTER TABLE work_entries ADD COLUMN motor_vehicle_id VARCHAR(64)"
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
def create_app(config_path=None):
|
def create_app(config_path=None):
|
||||||
app = Flask(__name__, instance_relative_config=True)
|
app = Flask(__name__, instance_relative_config=True)
|
||||||
|
|
||||||
@@ -34,6 +59,7 @@ def create_app(config_path=None):
|
|||||||
app.register_blueprint(reports_bp)
|
app.register_blueprint(reports_bp)
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
|
_migrate_db(app)
|
||||||
db.create_all()
|
db.create_all()
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class WorkEntry(db.Model):
|
|||||||
id: so.Mapped[int] = so.mapped_column(primary_key=True)
|
id: so.Mapped[int] = so.mapped_column(primary_key=True)
|
||||||
date: so.Mapped[date] = so.mapped_column(sa.Date, unique=True, nullable=False)
|
date: so.Mapped[date] = so.mapped_column(sa.Date, unique=True, nullable=False)
|
||||||
journey_profile_id: so.Mapped[str | None] = so.mapped_column(sa.String(64), nullable=True)
|
journey_profile_id: so.Mapped[str | None] = so.mapped_column(sa.String(64), nullable=True)
|
||||||
|
motor_vehicle_id: so.Mapped[str | None] = so.mapped_column(sa.String(64), nullable=True)
|
||||||
day_type: so.Mapped[str] = so.mapped_column(sa.String(16), nullable=False, default="WORK")
|
day_type: so.Mapped[str] = so.mapped_column(sa.String(16), nullable=False, default="WORK")
|
||||||
comment: so.Mapped[str | None] = so.mapped_column(sa.Text, nullable=True)
|
comment: so.Mapped[str | None] = so.mapped_column(sa.Text, nullable=True)
|
||||||
created_at: so.Mapped[datetime] = so.mapped_column(sa.DateTime, default=datetime.utcnow)
|
created_at: so.Mapped[datetime] = so.mapped_column(sa.DateTime, default=datetime.utcnow)
|
||||||
|
|||||||
Reference in New Issue
Block a user