Skip to content

v0.3-alpha

Latest

Choose a tag to compare

@DerTraurigeHund DerTraurigeHund released this 12 Aug 19:20
· 1 commit to main since this release
5df1fd2

Changelog

Version: v0.3-alpha
Datum: 2025-08-12

Hinweis: Baseline war v0.2-alpha (ganz am Anfang dieses Chats). Diese Version (v0.3-alpha) fasst alle Änderungen, Erweiterungen und Verbesserungen zusammen, die seit v0.2-alpha implementiert wurden.

Übersicht (Kurz)

v0.3-alpha erweitert das Mini‑ORM erheblich: Connection‑Management & Pooling, robustere Transaktionen mit Savepoints, persistente Migrations‑Historie, Audit‑Trigger, umfangreiche DDL- und Batch‑Methoden, Soft‑Delete‑Integration in Queries, Hooks erweitert, Schema‑Caching, Typ‑Inference, Streaming für große Abfragen, Logging und viele Convenience‑Methoden (get_by, get_or_create, paginate_with_count, usw.).


Neu (Added)

  • Connection / Pooling

    • connect_pool(minconn, maxconn, **db_params)
    • close() / close_pool()
  • Logging & Observability

    • set_logger(fn) zum Registrieren eines Query‑Loggers
    • healthcheck() für einfache DB‑Erreichbarkeitsprüfung
    • explain(query, analyze=True) zur Abfrageoptimierung
  • Transaktionen & Savepoints

    • transaction() Contextmanager mit Verschachtelung (innere Ebenen verwenden Savepoints)
    • savepoint(name=None) separater Savepoint‑Context
  • Migrations‑Framework (persistente Historie)

    • schema_migrations Tabelle wird angelegt
    • run_migrations() protokolliert ausgeführte Migrationen
    • add_migration(name, fn) zur Registrierung
  • Audit‑Trail

    • enable_audit_trail(table, audit_table="audit_log") legt Trigger und Audit‑Tabelle an
  • Hooks

    • Global und tabellenspezifische BEFORE/AFTER Hooks (register_before_insert, register_after_insert)
    • BEFORE‑Hooks können Daten mutieren; AFTER‑Hooks werden exceptionsicher ausgeführt
  • Soft‑Delete

    • soft_delete(), restore_soft_deleted(), purge_soft_deleted_older_than()
    • automatische Berücksichtigung von deleted-Spalte in Abfragen (exclude_deleted flag)
  • CRUD / Convenience

    • get_by(), first(), last(), get_or_create()
    • paginate_with_count()
    • list_all_ids()
    • exists_by_id()
    • to_dict(), refresh(), clone_row(), copy_row_to_table()
  • Upsert / Bulk / Batch

    • upsert(table, conflict_cols, values, update_cols=None) (RETURNING id)
    • bulk_create(rows) (execute_values)
    • bulk_update(rows, key="id") via VALUES/... FROM‑Konstrukt
    • execute_batch(query, params, page_size) (psycopg2.extras.execute_batch)
  • Streaming & große Datenmengen

    • stream_query(query, params=(), fetch_size=1000) mit serverseitigem Cursor
  • Schema / DDL

    • inspect_schema(table) mit TTL‑Cache (set_schema_cache_ttl)
    • ensure_columns(table, columns: Dict[col, SQLType]) für Mehrfach‑ALTER
    • create_table, drop_table, add_index, add_unique, add_foreign_key, drop_constraint, rename_column, drop_column
    • add_timestamps(table) + Trigger für updated_at
    • ensure_version_column(table, version_col="version") für Optimistic Locking
    • vacuum_analyze(table=None)
  • Optimistic Locking

    • save_with_version(version_col="version") mit vorherigem ensure_version_column
  • Aggregates

    • aggregate(table, func, column, **conditions) (SUM/MIN/MAX/AVG/COUNT etc.)
  • Schema‑Caching und Typ‑Inference

    • automatisches Anlegen neuer Spalten mit inferiertem SQL‑Typ (TEXT, BOOLEAN, BIGINT, JSONB, TIMESTAMP, ...)
    • Cache default TTL = 300s, konfigurierbar via set_schema_cache_ttl

Verbesserungen (Changed)

  • _get_cursor() / Connection-Handling

    • Unterstützung für Pooling vs. Einzelverbindung, Cursor‑Commit/Rollback jetzt korrekt mit/ohne outer transaction
    • Cursor wird immer geschlossen; Pool‑Verbindung wird nur zurückgegeben, wenn nicht in globaler transaction()
  • transaction()

    • Verschachtelung mittels Savepoints (innere Scope → SAVEPOINT / RELEASE / ROLLBACK TO)
    • threadlocal Speicherung der Verbindung/Depth (Thread‑sicherer Kontext)
  • Hooks

    • Unterstützung globaler ("*") Hooks neben tabellenspezifischen Hooks
    • BEFORE‑Hooks werfen Fehler (abbruch); AFTER‑Hooks werden log‑sicher ausgeführt (Fehler werden unterdrückt)
  • Schema‑Inspektion/Cache

    • TTL‑Cache zur Verminderung von information_schema‑Abfragen, Cache‑Invalidierung nach DDL‑Operationen
  • Soft‑Delete

    • Automatische Filterung (exclude_deleted=True) in find_ids/get_all/paginate/count/exists
  • create(), bulk_create(), upsert()

    • Optional: Spaltentypen explizit per column_types oder infer_types=True
    • Fehlende Spalten werden automatisch mit sinnvoller Typwahl angelegt
  • Fehlerbehandlung

    • Logging des SQL (wenn Logger gesetzt) ohne das Ausführen zu beeinflussen
    • Hooks und Logger dürfen nicht die DB‑Operationen destabilisieren

Fehlerbehebungen (Fixed)

  • Resource‑Leaks beim Pooling verhindert (Cursor schließen, putconn sicherstellen)
  • Transaktionslogik: commit/rollback wird korrekt nur am Outermost‑Level durchgeführt
  • Bulk‑Inserts: execute_values korrekt eingesetzt und RETURNING id gelesen
  • Schema‑Änderungen invalidieren nun Cache korrekt

Entfernt / Deprecated

  • Keine Methoden wurden absichtlich entfernt; einige Signaturen wurden erweitert (kompatibel, aber erweiterte Parameter vorhanden):
    • create(...) Signature erweitert um column_types & infer_types
    • register_before_insert/register_after_insert nehmen jetzt Optional table (None/"*" = global)

Breaking Changes / Migration Notes

  • Wenn du externe Code hast, der register_before_insert(table, fn) mit table None benutzt hat, das Verhalten ist jetzt konsistent: verwende "*" oder None für globale Hooks.
  • create() akzeptiert jetzt zusätzliche optionale Parameter (column_types, infer_types) — bestehende Aufrufe bleiben kompatibel.
  • transaction(): vorherige Implementierung kann in seltenen Fällen ein anderes Verhalten beim nested transaction handling gehabt haben; überprüfe komplexe Migrationsskripts, die sich auf implicit commits verlassen.
  • run_migrations() legt nun persistente Tabelle schema_migrations an. Falls du bereits eine Tabelle mit anderem Schema namens schema_migrations hast, müssten Konflikte überprüft werden.
  • add_timestamps() und enable_audit_trail() legen PL/pgSQL‑Funktionen/Trigger an — falls Namen kollidieren, passe Namen an.

Empfehlung vor Upgrade:

  • Backup der DB / Schema.
  • Prüfe vorhandene Tabellen schema_migrations / audit_log auf Namenskonflikte.
  • Führe run_migrations() in Testumgebung aus.
  • Falls du save_with_version einsetzen willst: zuerst ensure_version_column(table).

Upgrade‑/Migrations‑Beispiel

  1. Verbindung herstellen (Test):

    • DM.connect_pool(...)
  2. Logging einschalten (optional):

    • DM.set_logger(lambda q,p: print(q, p))
  3. Migrationen ausführen:

    • DM.add_migration("001_add_index_users_email", lambda: DM.add_index("users","email", unique=True))
    • DM.run_migrations()
  4. Audit aktivieren (optional):

    • DM.enable_audit_trail("users")
  5. Versionierung (optional):

    • DM.ensure_version_column("users")

Beispiele (neues Verhalten)

  • get_or_create:
obj, created = DM.get_or_create("users", defaults={"name":"X"}, email="a@b.c")
  • Upsert:
uid = DM.upsert("users", conflict_cols=["email"], values={"email":"a@b.c","name":"Ada"})
  • Transaction mit Savepoint:
with DM.transaction():
    a = DM.create("t", x=1)
    with DM.savepoint():
        b = DM.create("t", x=2)
        # Fehler -> nur Savepoint rollback
  • Streaming:
for row in DM.stream_query("SELECT * FROM big_table"):
    process(row)

Sonstiges / Hinweise

  • Default Schema‑Cache TTL = 300 Sekunden (konfigurierbar)
  • Typ‑Inference ist heuristisch; bei Bedarf explizit column_types übergeben
  • Alle neu hinzugefügten Features sind auf SQL‑Injection geschützt (sql.Identifier, Parameterbindung). Achte dennoch bei dynamischen SQL‑Fragments (z. B. aggregate func) auf Validierung.