Files
projet_gestion_commande/scripts/import_users.py
T
2026-04-21 09:23:43 +02:00

163 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Import users depuis data3.txt (format psql pipe-séparé) vers PostgreSQL.
Usage : python3 import_users.py [--dry-run]
"""
import os
import sys
import psycopg2
DB_CONFIG = {
"host": "localhost",
"port": 5432,
"user": "",
"password": "",
"dbname": "",
}
DATA_FILE = os.path.join(os.path.dirname(__file__), "data3.txt")
DRY_RUN = "--dry-run" in sys.argv
# Colonnes dans data3.txt — None = ignoré (push_token supprimé)
SOURCE_COLUMNS = [
"id",
"username",
"password",
"role",
"total",
"livraison",
"created_at",
"updated_at",
]
def parse_value(v: str):
v = v.strip()
if v == "" or v.lower() == "null":
return None
if v.lower() == "t":
return True
if v.lower() == "f":
return False
return v
def load_data(path: str) -> list[list]:
rows = []
with open(path, encoding="utf-8") as f:
for line in f:
line = line.rstrip("\n")
if not line.strip():
continue
if (
set(
line.replace("|", "")
.replace("+", "")
.replace("-", "")
.replace(" ", "")
)
== set()
):
continue
parts = line.split("|")
values = (
[parse_value(p) for p in parts[:-1]]
if parts[-1].strip() == ""
else [parse_value(p) for p in parts]
)
# Ignorer la ligne d'en-tête
if values and values[0] == "id":
continue
if values:
rows.append(values)
return rows
def main():
rows = load_data(DATA_FILE)
if not rows:
print("❌ Aucune ligne trouvée dans data3.txt")
sys.exit(1)
print(f"📂 {len(rows)} lignes lues depuis {DATA_FILE}")
data_col_count = len(rows[0])
print(
f"📋 Colonnes data3.txt : {data_col_count} | SOURCE_COLUMNS définis : {len(SOURCE_COLUMNS)}"
)
if data_col_count != len(SOURCE_COLUMNS):
print(
f"⚠️ Ajuste SOURCE_COLUMNS ({len(SOURCE_COLUMNS)} définis, {data_col_count} dans le fichier)"
)
sys.exit(1)
insert_cols = [col for col in SOURCE_COLUMNS if col is not None and col != "id"]
insert_cols_with_id = ["id"] + insert_cols
placeholders = ", ".join(["%s"] * len(insert_cols_with_id))
col_names = ", ".join(insert_cols_with_id)
update_expr = ", ".join(f"{c} = EXCLUDED.{c}" for c in insert_cols)
sql = f"""
INSERT INTO users ({col_names})
VALUES ({placeholders})
ON CONFLICT (username) DO UPDATE SET {update_expr}
"""
conn = psycopg2.connect(**DB_CONFIG)
conn.autocommit = False
cur = conn.cursor()
inserted = updated = errors = 0
for i, row in enumerate(rows, 1):
row_dict = {}
for pos, col in enumerate(SOURCE_COLUMNS):
if col is None:
continue
row_dict[col] = row[pos] if pos < len(row) else None
values = [row_dict.get(c) for c in insert_cols_with_id]
username = row_dict.get("username", "?")
try:
if DRY_RUN:
print(f" [DRY-RUN] {i}. {username}{row_dict}")
inserted += 1
continue
cur.execute("SELECT 1 FROM users WHERE username = %s", (username,))
exists = cur.fetchone() is not None
cur.execute(sql, values)
if exists:
updated += 1
else:
inserted += 1
except Exception as e:
print(f" ❌ Erreur ligne {i} ({username}) : {e}")
conn.rollback()
errors += 1
if not DRY_RUN:
cur.execute(
"SELECT setval('users_id_seq', COALESCE((SELECT MAX(id) FROM users), 1))"
)
conn.commit()
cur.close()
conn.close()
print(f"\n{'🔍 DRY-RUN — ' if DRY_RUN else ''}✅ Terminé")
print(f" Insérés : {inserted}")
print(f" Mis à jour : {updated}")
print(f" Erreurs : {errors}")
print(" ️ Séquence users_id_seq resynchronisée sur MAX(id)")
if __name__ == "__main__":
main()