neues skript sql_dump_diff.py zum Vergleich von 2 sql-dumps.

- leere, frisch initialisierte Datenbanken der Versionen verglichen
- datasetprogramme erkennen jetzt auch suche nach standardtabellen wie uom
This commit is contained in:
2026-08-22 17:45:46 +02:00
parent c0dd24b6c5
commit a55774eff2
19 changed files with 78583 additions and 269 deletions
+60
View File
@@ -25,6 +25,27 @@ Pro Modell wird zusätzlich `persisted` erkannt (erbt die Klasse `ModelSQL`
o. ä., oder nur `ModelView` - dann ist es ein reines Wizard-/
Transient-Formular ohne eigene Tabelle).
Verfolgt zusätzlich ganz normale **Python-Vererbung innerhalb derselben
Datei**: erbt eine Klasse mit eigenem `__name__` von einer anderen lokalen
Klasse - z. B. `class BOMOutput(BOMInput): __name__ = 'production.bom.output'`
in `production/bom.py`, die selbst keine einzige `fields.X(...)`-Zeile
deklariert, sondern alle Felder von `BOMInput` übernimmt - werden die
geerbten Felder mit aufgenommen (eigene Felder überschreiben geerbte bei
Namensgleichheit). Ohne das sähe ein rein über Vererbung wiederverwendetes
Modell wie eines OHNE Felder aus, und Änderungen daran (z. B. eine
Feldumbenennung im Elternteil) blieben komplett unsichtbar - genau das hat
`sql_dump_diff.py` (Schritt 4) einmal live aufgedeckt.
Die Basisklassen-Auflösung ist bewusst auf "gleiche Datei" beschränkt
(nicht "gleiches Modul"): derselbe lokale Klassenname wie `Cron` taucht
innerhalb eines Moduls oft mehrfach für völlig unterschiedliche Klassen
auf (Tryton-Konvention: eine PoolMeta-Erweiterung heißt oft genauso wie
das Original, z. B. `currency/currency.py` definiert `class Cron(ModelSQL,
ModelView): __name__ = 'currency.cron'`, während `currency/ir.py`
unabhängig davon eine andere Klasse `class Cron(metaclass=PoolMeta):` zur
Erweiterung von `ir.cron` definiert) - ein modulweites Registry würde sich
da gegenseitig überschreiben.
```bash
python3 extract_model_tree.py --repo /mnt/tryton \
--modules company country currency party product ... \
@@ -81,11 +102,50 @@ python3 model_coverage.py --model-tree reports/model_tree_5.0.json \
--report reports/coverage_5.0.md
```
### 4. `sql_dump_diff.py` – gegen den echten DB-Zustand validieren
Alles bisherige ist reine Code-Analyse. Zum Cross-Check: zwei mit
`pg_dump` (Klartext-Format) erzeugte Dumps frisch initialisierter (leerer)
Datenbanken beider Versionen strukturell vergleichen - Tabellen
entfernt/neu, Spalten hinzugefügt/entfernt/Typ geändert, Zeilenzahl
(z. B. mehr XML-Fixture-Daten in der neueren Version). Zeilen werden
bereits vollständig geparst (für eine spätere inhaltliche
Vergleichs-Erweiterung, sobald es Snapshots mit echten Testdaten gibt),
aktuell nutzt der Report davon aber nur die Zeilenzahl.
Mit `--model-diff reports/model_diff.json` wird pro betroffener Tabelle
zusätzlich geprüft, ob die rein statische Code-Analyse (Schritt 2)
dieselbe Änderung schon vorhergesagt hatte (Modellname -> Tabellenname:
Punkte durch Unterstriche ersetzen, wie `extract_updates.py`/
`compare_snapshots.py` es auch tun) - Übereinstimmung bzw. Abweichung wird
markiert.
```bash
python3 sql_dump_diff.py --dump-a data/leer5.sql --label-a 5.0 \
--dump-b data/leer8.sql --label-b 8.0 \
--model-diff reports/model_diff.json \
--output reports/dump_diff_5.0_8.0.json --report reports/dump_diff_5.0_8.0.md
```
**Stand:** 78 von 92 vergleichbaren Fällen stimmen überein (~85%). Die
verbleibenden Abweichungen gehen meist in eine erwartbare Richtung: die
Code-Analyse findet MEHR Veränderung, als im leeren DB-Schema sichtbar
ist (z. B. ein entferntes Function-Feld ohne eigene Spalte, oder
Selection-Wertänderungen ohne Typänderung) - kein Fehler, sondern zwei
Werkzeuge, die unterschiedliche Ebenen messen (Python-Feld-Definition vs.
physisches SQL-Schema). Der `production.bom.output`-Fund oben (Schritt 1)
kam genau aus einer vorherigen Abweichung dieser Art zustande.
## Bekannte Grenzen
- Rein statische Analyse: Felder, die nicht als einfaches
`name = fields.X(...)` auf Klassenebene stehen (z. B. per Schleife/Helper
dynamisch erzeugt), werden nicht erkannt.
- Python-Vererbung wird nur INNERHALB derselben Datei aufgelöst (s. o.).
Erbt eine Klasse von einer Basisklasse aus einer anderen Datei desselben
oder eines anderen Moduls (Import statt lokaler Definition), werden
deren Felder nicht gefunden - unauffällig, aber ein bekannter blinder
Fleck.
- `persisted`-Erkennung ist eine Textsuche über die Basisklassen-Ausdrücke
(`ModelSQL`/`Workflow`/`DeactivableMixin`) - deckt den Normalfall ab, ist
aber kein echtes Type-Checking.