menu 1 2 3 4 5 7 operationnels
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
Application séquentielle des migrations SQL du dossier `migrations/`
|
||||
sur la base « bolsa ». À exécuter depuis la racine du projet :
|
||||
|
||||
python migrations/apply_migrations.py
|
||||
|
||||
Lit la configuration MySQL depuis les variables d'environnement (.env).
|
||||
N'applique que les fichiers non déjà enregistrés dans la table
|
||||
`__migrations__` (créée automatiquement).
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pymysql
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
MIGRATIONS_DIR = Path(__file__).parent
|
||||
|
||||
|
||||
def get_connection():
|
||||
return pymysql.connect(
|
||||
host=os.environ.get("MYSQL_HOST", "db"),
|
||||
port=int(os.environ.get("MYSQL_PORT", "3306")),
|
||||
user=os.environ.get("MYSQL_USER", "jfgiraud"),
|
||||
password=os.environ.get("MYSQL_PASSWORD", ""),
|
||||
database=os.environ.get("MYSQL_DATABASE", "bolsa"),
|
||||
charset="utf8mb4",
|
||||
autocommit=False,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
conn = get_connection()
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"CREATE TABLE IF NOT EXISTS `__migrations__` ("
|
||||
" `id` int NOT NULL AUTO_INCREMENT,"
|
||||
" `filename` varchar(255) NOT NULL,"
|
||||
" `applied_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,"
|
||||
" PRIMARY KEY (`id`),"
|
||||
" UNIQUE KEY `idx_filename` (`filename`)"
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
cur.execute("SELECT filename FROM `__migrations__`")
|
||||
applied = {row[0] for row in cur.fetchall()}
|
||||
|
||||
sql_files = sorted(
|
||||
f for f in MIGRATIONS_DIR.glob("*.sql")
|
||||
if f.name != "schema.sql"
|
||||
)
|
||||
|
||||
if not sql_files:
|
||||
print("Aucune migration à appliquer.")
|
||||
return
|
||||
|
||||
for sql_file in sql_files:
|
||||
if sql_file.name in applied:
|
||||
print(f"[déjà appliquée] {sql_file.name}")
|
||||
continue
|
||||
|
||||
print(f"[application] {sql_file.name}")
|
||||
sql = sql_file.read_text(encoding="utf-8")
|
||||
# Découpage sur les ';' pour exécuter instruction par instruction
|
||||
statements = [s.strip() for s in sql.split(";") if s.strip()]
|
||||
for stmt in statements:
|
||||
cur.execute(stmt)
|
||||
cur.execute(
|
||||
"INSERT INTO `__migrations__` (filename) VALUES (%s)",
|
||||
(sql_file.name,),
|
||||
)
|
||||
conn.commit()
|
||||
print(f"[OK] {sql_file.name}")
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
print(f"[ERREUR] {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,110 @@
|
||||
-- =====================================================================
|
||||
# Schéma de la base « bolsa » — version de référence (snake_case)
|
||||
-- =====================================================================
|
||||
# Tables : login, actions, societe, compte, ordre, ordre_pied
|
||||
# Encodage : utf8mb4 / utf8mb4_0900_ai_ci
|
||||
# Ce fichier est exécuté automatiquement par Docker sur une base vierge
|
||||
# (monté dans /docker-entrypoint-initdb.d/). Sur une base existante, les
|
||||
# CREATE TABLE IF NOT EXISTS sont sans effet.
|
||||
-- =====================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `login` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`login` varchar(50) NOT NULL,
|
||||
`nom` varchar(100) NOT NULL,
|
||||
`prenom` varchar(100) NOT NULL,
|
||||
`mail` varchar(255) NOT NULL,
|
||||
`pass` varchar(255) NOT NULL,
|
||||
`actif` tinyint(1) DEFAULT NULL,
|
||||
`creer_le` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`modifie_le` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`reset_token` varchar(255) DEFAULT NULL,
|
||||
`reset_token_created_at` timestamp NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_login` (`login`),
|
||||
UNIQUE KEY `idx_mail` (`mail`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `actions` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`isin` varchar(50) NOT NULL,
|
||||
`ticker` varchar(50) DEFAULT NULL,
|
||||
`company_name` varchar(255) DEFAULT NULL,
|
||||
`exchange` varchar(50) NOT NULL,
|
||||
`pays` varchar(50) NOT NULL,
|
||||
`currency` varchar(10) NOT NULL,
|
||||
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `isin` (`isin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `societe` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`nom` varchar(60) NOT NULL,
|
||||
`forme` varchar(10) NOT NULL,
|
||||
`capital` int NOT NULL,
|
||||
`siren` varchar(20) NOT NULL,
|
||||
`siret` varchar(20) NOT NULL,
|
||||
`rcs` varchar(50) NOT NULL,
|
||||
`tva` varchar(50) NOT NULL,
|
||||
`naf` varchar(10) NOT NULL,
|
||||
`tel` varchar(30) NOT NULL,
|
||||
`web` varchar(100) NOT NULL,
|
||||
`mail` varchar(100) NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `compte` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`id_societe` int NOT NULL,
|
||||
`date_operation` date NOT NULL,
|
||||
`debit` decimal(15,2) DEFAULT '0.00',
|
||||
`credit` decimal(15,2) DEFAULT '0.00',
|
||||
`libelle` text,
|
||||
`source` enum('manuel','ordre') NOT NULL DEFAULT 'manuel',
|
||||
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_compte_societe` (`id_societe`),
|
||||
CONSTRAINT `fk_compte_societe` FOREIGN KEY (`id_societe`)
|
||||
REFERENCES `societe` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ordre` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`id_societe` int NOT NULL,
|
||||
`isin` varchar(50) NOT NULL,
|
||||
`plus_value` decimal(19,4) NOT NULL DEFAULT '0.0000',
|
||||
`date_plus_value` date DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_ordre_societe` (`id_societe`),
|
||||
KEY `fk_ordre_actions` (`isin`),
|
||||
CONSTRAINT `fk_ordre_societe` FOREIGN KEY (`id_societe`)
|
||||
REFERENCES `societe` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT `fk_ordre_actions` FOREIGN KEY (`isin`)
|
||||
REFERENCES `actions` (`isin`) ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `ordre_pied` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`id_entete` int NOT NULL,
|
||||
`date_op` date NOT NULL,
|
||||
`quantite` int NOT NULL,
|
||||
`prix_brut` decimal(19,4) DEFAULT NULL,
|
||||
`frais_broker` decimal(19,4) DEFAULT NULL,
|
||||
`frais_etat` decimal(19,4) DEFAULT NULL,
|
||||
`frais_autre` decimal(19,4) DEFAULT NULL,
|
||||
`sens` enum('achat','vente') NOT NULL,
|
||||
`position` enum('long','short') NOT NULL,
|
||||
`etat` enum('actif','soldé','annulé') NOT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_ordre_pied_entete` (`id_entete`),
|
||||
CONSTRAINT `fk_ordre_pied_entete` FOREIGN KEY (`id_entete`)
|
||||
REFERENCES `ordre` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
|
||||
Reference in New Issue
Block a user