Compare commits
5 Commits
albert-pat
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f64aeaf31c | |||
| c444a3f6ac | |||
| 2ed4a107b9 | |||
| b2959bebdb | |||
| 6bccca2864 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Testskripte werden nicht versioniert (enthalten ggf. sensible Produktionsskripte)
|
||||||
|
testskripte/
|
||||||
74
README.md
74
README.md
@@ -0,0 +1,74 @@
|
|||||||
|
# RepoVizChecker
|
||||||
|
|
||||||
|
Ein Python-Werkzeug zum Abgleich von **RepoViz-Annotationen** mit dem tatsächlich verwendeten SQL-Code in Kornshell-Skripten (`.ksh`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Beschreibung
|
||||||
|
|
||||||
|
KSH-Skripte enthalten häufig RepoViz-Metadaten in Form von Kommentar-Annotationen:
|
||||||
|
|
||||||
|
```ksh
|
||||||
|
#@modul: mein_skript.ksh
|
||||||
|
#@quelle: TABELLE_A, TABELLE_B
|
||||||
|
#@ziel: TABELLE_Z
|
||||||
|
```
|
||||||
|
|
||||||
|
`repovizcheck.py` liest diese Annotationen aus und vergleicht sie mit den Tabellennamen, die im Code über `$SCHEMA.<TABELLE>` bzw. `${SCHEMA}.<TABELLE>` tatsächlich referenziert werden.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- ✅ Liest `#@modul:`, `#@quelle:` und `#@ziel:` Annotationen aus dem KSH-Skript
|
||||||
|
- ✅ Erkennt verwendete Tabellen per Regex (`$SCHEMA.*` / `${SCHEMA}.*`)
|
||||||
|
- ✅ Vergleich **Repo → SQL**: Sind alle dokumentierten Tabellen im Code vorhanden?
|
||||||
|
- ✅ Vergleich **SQL → Repo**: Sind alle Code-Tabellen in den Annotationen dokumentiert?
|
||||||
|
- ✅ Prüft, ob der Skriptname in `#@modul:` eingetragen ist
|
||||||
|
- ✅ Encoding-Fallback: UTF-8 → ISO-8859-1
|
||||||
|
- ✅ Temporäre Tabellen (`TMP_*`) werden automatisch ignoriert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- Python 3.x
|
||||||
|
- Keine zusätzlichen Pakete erforderlich (nur Standardbibliothek)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Aufruf
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python repovizcheck.py <skript.ksh>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Beispiel
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python repovizcheck.py C:\projekte\etl_job.ksh
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ausgabe (Übersicht)
|
||||||
|
|
||||||
|
| Abschnitt | Beschreibung |
|
||||||
|
|---|---|
|
||||||
|
| **RepoViz-Informationen** | Sortierte Ausgabe von Modul, Quell- und Zieltabellen |
|
||||||
|
| **Modul-Check** | Ist der Skriptname in `#@modul:` eingetragen? |
|
||||||
|
| **Repo → SQL** | Welche dokumentierten Tabellen sind im Code vorhanden / fehlen? |
|
||||||
|
| **SQL → Repo** | Welche Code-Tabellen sind dokumentiert / nicht dokumentiert? |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- Es werden ausschließlich `.ksh`-Dateien akzeptiert (case-insensitive).
|
||||||
|
- Tabellennamen werden für alle Vergleiche in **Großbuchstaben** normalisiert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Lizenz
|
||||||
|
|
||||||
|
Internes Werkzeug – Deutsche Telekom AG
|
||||||
|
|||||||
511
repovizcheck.py
511
repovizcheck.py
@@ -1,256 +1,255 @@
|
|||||||
"""
|
#!/usr/bin/env python
|
||||||
repovizcheck.py
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
Kurzbeschreibung:
|
repovizcheck.py
|
||||||
Dieses Skript vergleicht RepoViz-Metadaten (Annotationen in Kornshell-Skripten: "#@modul:", "#@quelle:", "#@ziel:")
|
|
||||||
mit tatsächlich im Skript verwendeten Tabellen (Erkennung über $SCHEMA.<TABELLE> oder ${SCHEMA}<TABELLE>). Es
|
Kurzbeschreibung:
|
||||||
ermöglicht einen schnellen Abgleich, welche Tabellen in RepoViz dokumentiert sind und welche im Code auftauchen.
|
Dieses Skript vergleicht RepoViz-Metadaten (Annotationen in Kornshell-Skripten: "#@modul:", "#@quelle:", "#@ziel:")
|
||||||
|
mit tatsächlich im Skript verwendeten Tabellen (Erkennung über $SCHEMA.<TABELLE> oder ${SCHEMA}<TABELLE>). Es
|
||||||
Aufruf:
|
ermöglicht einen schnellen Abgleich, welche Tabellen in RepoViz dokumentiert sind und welche im Code auftauchen.
|
||||||
python repovizcheck.py <skript.ksh>
|
|
||||||
|
Aufruf:
|
||||||
Wichtige Hinweise:
|
python repovizcheck.py <skript.ksh>
|
||||||
- Akzeptierte Dateiendung: .ksh (case-insensitive).
|
|
||||||
- Kodierung: versucht zunächst UTF-8, bei Fehlern Fallback auf ISO-8859-1.
|
Wichtige Hinweise:
|
||||||
- Tabellennamen werden für Vergleiche normalisiert (Uppercase); Regex-Parsing wurde robustifiziert.
|
- Akzeptierte Dateiendung: .ksh (case-insensitive).
|
||||||
"""
|
- Kodierung: versucht zunächst UTF-8, bei Fehlern Fallback auf ISO-8859-1.
|
||||||
|
- Tabellennamen werden für Vergleiche normalisiert (Uppercase); Regex-Parsing wurde robustifiziert.
|
||||||
from __future__ import print_function
|
"""
|
||||||
import sys
|
|
||||||
import re
|
from __future__ import print_function
|
||||||
import os.path as p
|
import sys
|
||||||
import argparse
|
import re
|
||||||
|
import os.path as p
|
||||||
print(r" ____ __ ___ ____ _ _ ")
|
import argparse
|
||||||
print(r"| _ \ ___ _ __ ___ \ \ / (_)____ / ___| |__ ___ ___| | _____ _ __ ")
|
import io
|
||||||
print(r"| |_) / _ \ '_ \ / _ \ \ \ / /| |_ / | | | '_ \ / _ \/ __| |/ / _ \ '__|")
|
|
||||||
print(r"| _ < __/ |_) | (_) | \ V / | |/ / | |___| | | | __/ (__| < __/ | ")
|
print(r" ____ __ ___ ____ _ _ ")
|
||||||
print(r"|_| \_\___| .__/ \___/ \_/ |_/___| \____|_| |_|\___|\___|_|\_\___|_| ")
|
print(r"| _ \ ___ _ __ ___ \ \ / (_)____ / ___| |__ ___ ___| | _____ _ __ ")
|
||||||
print(r" |_| ")
|
print(r"| |_) / _ \ '_ \ / _ \ \ \ / /| |_ / | | | '_ \ / _ \/ __| |/ / _ \ '__|")
|
||||||
|
print(r"| _ < __/ |_) | (_) | \ V / | |/ / | |___| | | | __/ (__| < __/ | ")
|
||||||
|
print(r"|_| \_\___| .__/ \___/ \_/ |_/___| \____|_| |_|\___|\___|_|\_\___|_| ")
|
||||||
such_quelle = "#@quelle:" #
|
print(r" |_| ")
|
||||||
such_ziel = "#@ziel:" #
|
|
||||||
such_modul = "#@modul:" #
|
|
||||||
|
such_quelle = "#@quelle:" #
|
||||||
allezeilen = [] # Das Skript wird zeilenwiese in diese Liste geschrieben, eine Zeile gleich ein Element der Liste
|
such_ziel = "#@ziel:" #
|
||||||
kommentarzeilen = [] # Ein Teil der nicht benoetigten Zeilen kommt in diese Liste
|
such_modul = "#@modul:" #
|
||||||
codezeilen = [] # Zeilen mit Code kommen in diese Liste
|
|
||||||
# Liste der gueltigen Dateiendungen (case-insensitive)
|
allezeilen = [] # Das Skript wird zeilenwiese in diese Liste geschrieben, eine Zeile gleich ein Element der Liste
|
||||||
perm_file_suffix = ['.ksh'] # Liste der gueltigen Dateiendungen
|
kommentarzeilen = [] # Ein Teil der nicht benoetigten Zeilen kommt in diese Liste
|
||||||
|
codezeilen = [] # Zeilen mit Code kommen in diese Liste
|
||||||
# Verwende argparse für robusten CLI-Aufruf und Help
|
# Liste der gueltigen Dateiendungen (case-insensitive)
|
||||||
parser = argparse.ArgumentParser(description='Check RepoViz annotations against SQL in a ksh script')
|
perm_file_suffix = ['.ksh'] # Liste der gueltigen Dateiendungen
|
||||||
parser.add_argument('sourcefile', help='Kornshell script to check (must end with .ksh)')
|
|
||||||
args = parser.parse_args()
|
# Verwende argparse für robusten CLI-Aufruf und Help
|
||||||
sourcefile = args.sourcefile
|
parser = argparse.ArgumentParser(description='Check RepoViz annotations against SQL in a ksh script')
|
||||||
|
parser.add_argument('sourcefile', help='Kornshell script to check (must end with .ksh)')
|
||||||
# Dateiendung prüfen (case-insensitive)
|
args = parser.parse_args()
|
||||||
file_suffix = p.splitext(sourcefile)[1].lower()
|
sourcefile = args.sourcefile
|
||||||
if file_suffix not in perm_file_suffix:
|
|
||||||
print() # Gib eine leere Zeile aus
|
# Dateiendung prüfen (case-insensitive)
|
||||||
print("Only Kornshell scripts can be processed.") # Gib diese Meldung aus
|
file_suffix = p.splitext(sourcefile)[1].lower()
|
||||||
print()
|
if file_suffix not in perm_file_suffix:
|
||||||
sys.exit(1)
|
print() # Gib eine leere Zeile aus
|
||||||
|
print("Only Kornshell scripts can be processed.") # Gib diese Meldung aus
|
||||||
|
print()
|
||||||
# Funktion zum Oeffnen einer Datei mit Pruefung
|
sys.exit(1)
|
||||||
def get(name):
|
|
||||||
'''Funktion zum Oeffnen einer Datei mit Pruefung (prüft Encoding)'''
|
|
||||||
# Versuche zuerst UTF-8, lese die gesamte Datei zur Validierung.
|
# Funktion zum Oeffnen einer Datei mit Pruefung
|
||||||
try:
|
def get(name):
|
||||||
f = open(name, "r", encoding='utf-8')
|
'''Funktion zum Oeffnen einer Datei mit Pruefung (prüft Encoding)'''
|
||||||
f.read() # komplette Datei lesen, um Decode-Fehler sicher zu erkennen
|
# io.open() wird verwendet, da es in Python 2 und 3 den encoding-Parameter unterstuetzt.
|
||||||
f.seek(0)
|
# Versuche zuerst UTF-8, lese die gesamte Datei zur Validierung.
|
||||||
return f
|
try:
|
||||||
except UnicodeDecodeError:
|
f = io.open(name, "r", encoding='utf-8')
|
||||||
# UTF-8 passt nicht — versuche ISO-8859-1
|
f.read() # komplette Datei lesen, um Decode-Fehler sicher zu erkennen
|
||||||
try:
|
f.seek(0)
|
||||||
f.close()
|
return f
|
||||||
return open(name, "r", encoding='ISO-8859-1')
|
except UnicodeDecodeError:
|
||||||
except IOError:
|
# UTF-8 passt nicht — versuche ISO-8859-1
|
||||||
print("")
|
try:
|
||||||
print("The File", name, "can't be opened with fallback encoding!")
|
f.close()
|
||||||
print("")
|
return io.open(name, "r", encoding='ISO-8859-1')
|
||||||
sys.exit(1)
|
except IOError:
|
||||||
except IOError:
|
print("")
|
||||||
print("")
|
print("The File", name, "can't be opened with fallback encoding!")
|
||||||
print("The File", name, "doesn't exist or can't be opened!")
|
print("")
|
||||||
print("")
|
sys.exit(1)
|
||||||
sys.exit(1)
|
except IOError:
|
||||||
except Exception:
|
print("")
|
||||||
# unerwarteter Fehler beim Lesen
|
print("The File", name, "doesn't exist or can't be opened!")
|
||||||
try:
|
print("")
|
||||||
f.close()
|
sys.exit(1)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
# unerwarteter Fehler beim Lesen
|
||||||
print("")
|
try:
|
||||||
print("Error reading the file", name)
|
f.close()
|
||||||
print("")
|
except Exception:
|
||||||
sys.exit(1)
|
pass
|
||||||
return None
|
print("")
|
||||||
|
print("Error reading the file", name)
|
||||||
|
print("")
|
||||||
# Funktion zum Erstellen einer Tabellenliste aus den RepoViz Informationen
|
sys.exit(1)
|
||||||
def erstelle_liste(datei, typ): # 2 Parameter
|
return None
|
||||||
'''Erstelle eine Liste aus der übergebenen Datei für den Typ der übergeben wurde'''
|
|
||||||
laenge = len(typ)
|
|
||||||
tabellenliste = []
|
# Funktion zum Erstellen einer Tabellenliste aus den RepoViz Informationen
|
||||||
fobj_in = get(datei)
|
def erstelle_liste(datei, typ): # 2 Parameter
|
||||||
for line in fobj_in:
|
'''Erstelle eine Liste aus der übergebenen Datei für den Typ der übergeben wurde'''
|
||||||
# entferne nur führende Leerzeichen vor der Prüfung
|
laenge = len(typ)
|
||||||
content = line.lstrip()
|
tabellenliste = []
|
||||||
if content.startswith(typ):
|
fobj_in = get(datei)
|
||||||
zeile = content[len(typ):].strip()
|
for line in fobj_in:
|
||||||
# entferne ein mögliches abschließendes Komma
|
# entferne nur führende Leerzeichen vor der Prüfung
|
||||||
if zeile.endswith(','):
|
content = line.lstrip()
|
||||||
zeile = zeile[:-1]
|
if content.startswith(typ):
|
||||||
liste = [it.strip() for it in zeile.split(',') if it.strip()]
|
zeile = content[len(typ):].strip()
|
||||||
for item in liste:
|
# entferne ein mögliches abschließendes Komma
|
||||||
# normalisiere auf Großbuchstaben für spätere Vergleiche
|
if zeile.endswith(','):
|
||||||
tabellenliste.append(item.strip().upper())
|
zeile = zeile[:-1]
|
||||||
fobj_in.close()
|
liste = [it.strip() for it in zeile.split(',') if it.strip()]
|
||||||
return tabellenliste
|
for item in liste:
|
||||||
|
# normalisiere auf Großbuchstaben für spätere Vergleiche
|
||||||
|
tabellenliste.append(item.strip().upper())
|
||||||
def trennzeile(typ): # Funktion zum Ausgeben einer 80 Zeichen breiten Trennzeile.
|
fobj_in.close()
|
||||||
'''
|
return tabellenliste
|
||||||
Erstellt eine 80 zeichenbreite Zeile mit dem übergebenen Zeichen
|
|
||||||
'''
|
|
||||||
print(typ * 80) # Das Trennzeichen ist variabel und wird der Funktion als Parameter uebergeben.
|
def trennzeile(typ): # Funktion zum Ausgeben einer Trennzeile.
|
||||||
|
'''
|
||||||
|
Erstellt eine 87 zeichenbreite Zeile mit dem übergebenen Zeichen
|
||||||
modulliste = erstelle_liste(sourcefile, such_modul) # Erstelle Liste mit den Modulen
|
'''
|
||||||
quelleliste = erstelle_liste(sourcefile, such_quelle) # Erstelle Liste mit den Quellen
|
print(typ * 87) # Das Trennzeichen ist variabel und wird der Funktion als Parameter uebergeben.
|
||||||
zielliste = erstelle_liste(sourcefile, such_ziel) # Erstelle Liste mit den Zielen
|
|
||||||
|
|
||||||
datei = get(sourcefile) # Oeffnen der Datei mit einer Funktion, die auch prueft ob die Datei existiert
|
modulliste = erstelle_liste(sourcefile, such_modul) # Erstelle Liste mit den Modulen
|
||||||
allezeilen = datei.readlines() # Lesen aller Zeilen in eine Liste
|
quelleliste = erstelle_liste(sourcefile, such_quelle) # Erstelle Liste mit den Quellen
|
||||||
datei.close()
|
zielliste = erstelle_liste(sourcefile, such_ziel) # Erstelle Liste mit den Zielen
|
||||||
|
|
||||||
# Versuch die Kommentarzeilen loszuwerden
|
datei = get(sourcefile) # Oeffnen der Datei mit einer Funktion, die auch prueft ob die Datei existiert
|
||||||
for zeile in allezeilen:
|
allezeilen = datei.readlines() # Lesen aller Zeilen in eine Liste
|
||||||
s = zeile.strip()
|
datei.close()
|
||||||
if not s:
|
|
||||||
# leere Zeilen überspringen
|
# Versuch die Kommentarzeilen loszuwerden
|
||||||
continue
|
for zeile in allezeilen:
|
||||||
if s.startswith('#@modul:'):
|
s = zeile.strip()
|
||||||
codezeilen.append(s)
|
if not s:
|
||||||
continue
|
# leere Zeilen überspringen
|
||||||
# Gruppiere typische Kommentar-/Meta-Zeilen (case-insensitive)
|
continue
|
||||||
up = s.upper()
|
if s.startswith('#@modul:'):
|
||||||
if s.startswith('#') or s.startswith('--') or up.startswith('J000') or up.startswith('SQLFILE') \
|
codezeilen.append(s)
|
||||||
or up.startswith('FMELDUNG') or up.startswith('ALTER') or up.startswith('F_TRUNCATE') \
|
continue
|
||||||
or up == 'FI' or up == 'IF' or up.startswith('F_RUNSTATS'):
|
# Gruppiere typische Kommentar-/Meta-Zeilen (case-insensitive)
|
||||||
kommentarzeilen.append(s)
|
up = s.upper()
|
||||||
else:
|
if s.startswith('#') or s.startswith('--') or up.startswith('J000') or up.startswith('SQLFILE') \
|
||||||
codezeilen.append(s)
|
or up.startswith('FMELDUNG') or up.startswith('ALTER') or up.startswith('F_TRUNCATE') \
|
||||||
|
or up == 'FI' or up == 'IF' or up.startswith('F_RUNSTATS'):
|
||||||
|
kommentarzeilen.append(s)
|
||||||
trennzeile("+")
|
else:
|
||||||
print("Sorted output of RepoViz information.")
|
codezeilen.append(s)
|
||||||
print("")
|
|
||||||
ausgabe = "{:10}{:}" # Definition AusgabeFormat 1.Feld begrenzt auf 10 Zeichen, das 2.Feld unbegrenzt
|
|
||||||
quelleliste.sort() # Sortiere Liste <quelleliste>
|
trennzeile("+")
|
||||||
zielliste.sort() # Sortiere Liste <zielliste>
|
print("Sorted output of RepoViz information.")
|
||||||
print(ausgabe.format(such_modul, modulliste)) # Ausgabe <modulliste>
|
print("")
|
||||||
print(ausgabe.format(such_quelle, quelleliste)) # Ausgabe <quelleliste>
|
ausgabe = "{:10}{:}" # Definition AusgabeFormat 1.Feld begrenzt auf 10 Zeichen, das 2.Feld unbegrenzt
|
||||||
print(ausgabe.format(such_ziel, zielliste)) # Ausgabe <zielliste>
|
quelleliste.sort() # Sortiere Liste <quelleliste>
|
||||||
|
zielliste.sort() # Sortiere Liste <zielliste>
|
||||||
# Vergleiche sourcefile mit modulliste hier einfuegen
|
print(ausgabe.format(such_modul, modulliste)) # Ausgabe <modulliste>
|
||||||
# Eventuell anpassen, es steht nur der Skriptname in den RepoVizInfos
|
print(ausgabe.format(such_quelle, quelleliste)) # Ausgabe <quelleliste>
|
||||||
trennzeile("~")
|
print(ausgabe.format(such_ziel, zielliste)) # Ausgabe <zielliste>
|
||||||
trennzeile("")
|
|
||||||
print("Comparison of given script name with RepoVizInformation")
|
# Vergleiche sourcefile mit modulliste hier einfuegen
|
||||||
# Vergleiche nur einmal, normalisiere auf Großbuchstaben
|
# Eventuell anpassen, es steht nur der Skriptname in den RepoVizInfos
|
||||||
script_basename = p.basename(sourcefile).upper()
|
trennzeile("~")
|
||||||
if script_basename in [m.strip().upper() for m in modulliste]:
|
trennzeile("")
|
||||||
print("Script", p.basename(sourcefile), "is in the RepoViz information!")
|
print("Comparison of given script name with RepoVizInformation")
|
||||||
else:
|
# Vergleiche nur einmal, normalisiere auf Großbuchstaben
|
||||||
print("Script", p.basename(sourcefile), "is missing in the RepoViz information!")
|
script_basename = p.basename(sourcefile).upper()
|
||||||
|
if script_basename in [m.strip().upper() for m in modulliste]:
|
||||||
# Suche Objekte anhand der RepoVizInformationen
|
print("Script", p.basename(sourcefile), "is in the RepoViz information!")
|
||||||
trennzeile("~")
|
else:
|
||||||
|
print("Script", p.basename(sourcefile), "is missing in the RepoViz information!")
|
||||||
print("")
|
|
||||||
print("Create a list of tables from the existing code: list <allezeilen>")
|
# Suche Objekte anhand der RepoVizInformationen
|
||||||
# Der Code steht schon in der Liste <codezeilen>
|
trennzeile("~")
|
||||||
neue_liste = []
|
|
||||||
# verbessertes Regex-Parsing: capture-Gruppe für Tabellennamen, compile einmal
|
print("")
|
||||||
regex = re.compile(r"(?:\$SCHEMA\.|\${SCHEMA}\.)\s*([A-Z0-9_]+)", re.IGNORECASE)
|
print("Create a list of tables from the existing code: list <allezeilen>")
|
||||||
# nutze Set für eindeutige Sammlung
|
# Der Code steht schon in der Liste <codezeilen>
|
||||||
neue_set = set()
|
neue_liste = []
|
||||||
for line in allezeilen:
|
# verbessertes Regex-Parsing: capture-Gruppe für Tabellennamen, compile einmal
|
||||||
for match in regex.findall(line):
|
regex = re.compile(r"(?:\$SCHEMA\.|\${SCHEMA}\.)\s*([A-Z0-9_]+)", re.IGNORECASE)
|
||||||
tabname = match.strip()
|
# nutze Set für eindeutige Sammlung
|
||||||
if not tabname:
|
neue_set = set()
|
||||||
continue
|
for line in allezeilen:
|
||||||
# ignoriere Variablen oder temporäre Tabellen
|
for match in regex.findall(line):
|
||||||
if tabname.startswith('$'):
|
tabname = match.strip()
|
||||||
continue
|
if not tabname:
|
||||||
tabname_norm = re.sub(r"[^A-Z0-9_]", "", tabname.upper())
|
continue
|
||||||
if tabname_norm and not tabname_norm.startswith('TMP_'):
|
# ignoriere Variablen oder temporäre Tabellen
|
||||||
neue_set.add(tabname_norm)
|
if tabname.startswith('$'):
|
||||||
neue_liste = sorted(neue_set)
|
continue
|
||||||
|
tabname_norm = re.sub(r"[^A-Z0-9_]", "", tabname.upper())
|
||||||
print("The list contains:", len(neue_liste), "entries")
|
if tabname_norm and not tabname_norm.startswith('TMP_'):
|
||||||
trennzeile("~")
|
neue_set.add(tabname_norm)
|
||||||
|
neue_liste = sorted(neue_set)
|
||||||
|
|
||||||
# Vergleich repo -> SQL
|
print("The list contains:", len(neue_liste), "entries")
|
||||||
# 2 Teile
|
trennzeile("~")
|
||||||
# Quelle - quelleliste
|
|
||||||
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
|
||||||
# trennzeile("#")
|
# Vergleich repo -> SQL
|
||||||
print("Are the tables of the list", such_quelle, "included in the SQL?")
|
# 2 Teile
|
||||||
trennzeile("~")
|
# Quelle - quelleliste
|
||||||
for item in quelleliste:
|
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
||||||
# quelleliste wurde in erstelle_liste bereits normalisiert (upper)
|
# trennzeile("#")
|
||||||
if item.upper() in neue_liste:
|
ausgabe = "{:12}{:55}{:20}" # Ausgabeformat: Label(12), Tabellenname(55), Status(20)
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
print("Are the tables of the list", such_quelle, "included in the SQL?")
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
trennzeile("~")
|
||||||
else:
|
for item in quelleliste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
# quelleliste wurde in erstelle_liste bereits normalisiert (upper)
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
if item.upper() in neue_liste:
|
||||||
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
# Quelle - zielliste
|
else:
|
||||||
# nehme Liste "zielliste" und suche damit in Liste "neue_liste"
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
trennzeile("~")
|
|
||||||
print("Are the tables of the list", such_ziel, "included in the SQL?")
|
# Quelle - zielliste
|
||||||
trennzeile("~")
|
# nehme Liste "zielliste" und suche damit in Liste "neue_liste"
|
||||||
for item in zielliste:
|
trennzeile("~")
|
||||||
if item.upper() in neue_liste:
|
print("Are the tables of the list", such_ziel, "included in the SQL?")
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
trennzeile("~")
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
for item in zielliste:
|
||||||
else:
|
if item.upper() in neue_liste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
else:
|
||||||
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
trennzeile("~")
|
|
||||||
print("Create unique sorted list from ", such_quelle, "and", such_ziel)
|
trennzeile("~")
|
||||||
q_z_liste = sorted({t.upper() for t in (quelleliste + zielliste)})
|
print("Create unique sorted list from ", such_quelle, "and", such_ziel)
|
||||||
|
q_z_liste = sorted({t.upper() for t in (quelleliste + zielliste)})
|
||||||
trennzeile("~")
|
|
||||||
|
trennzeile("~")
|
||||||
# Vergleich SQL -> repo
|
|
||||||
# Quelle - neue_liste
|
# Vergleich SQL -> repo
|
||||||
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
# Quelle - neue_liste
|
||||||
trennzeile("~")
|
# nehme Liste "quelleliste" und suche damit in Liste "neue_liste"
|
||||||
print("Are the tables from the SQL included in the RepoViz information?")
|
trennzeile("~")
|
||||||
print("Note: I've merged <#@quelle> and <#@ziel> into one list ")
|
print("Are the tables from the SQL included in the RepoViz information?")
|
||||||
trennzeile("~")
|
print("Note: I've merged <#@quelle> and <#@ziel> into one list ")
|
||||||
for item in neue_liste:
|
trennzeile("~")
|
||||||
if item in q_z_liste:
|
for item in neue_liste:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
if item in q_z_liste:
|
||||||
print(ausgabe.format("The Table", item, "is available"))
|
print(ausgabe.format("The Table", item, "is available"))
|
||||||
else:
|
else:
|
||||||
ausgabe = "{:12}{:40}{:20}"
|
print(ausgabe.format("The Table", item, "is not available"))
|
||||||
print(ausgabe.format("The Table", item, "is not available"))
|
|
||||||
|
trennzeile("+")
|
||||||
trennzeile("+")
|
print(r" _____ _ _____ _ ")
|
||||||
print(r" _____ _ _____ _ ")
|
print(r"|_ _| |__ ___ | ____|_ __ __| |")
|
||||||
print(r"|_ _| |__ ___ | ____|_ __ __| |")
|
print(r" | | | '_ \ / _ \ | _| | '_ \ / _` |")
|
||||||
print(r" | | | '_ \ / _ \ | _| | '_ \ / _` |")
|
print(r" | | | | | | __/ | |___| | | | (_| |")
|
||||||
print(r" | | | | | | __/ | |___| | | | (_| |")
|
print(r" |_| |_| |_|\___| |_____|_| |_|\__,_|")
|
||||||
print(r" |_| |_| |_|\___| |_____|_| |_|\__,_|")
|
print("")
|
||||||
print("")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user