Schema-Entdeckung mit mssql-python

Die mssql-python-Cursor-Klasse stellt neun Metadatenmethoden bereit, die ODBC-Katalogfunktionen zugeordnet sind. Nutzen Sie diese Methoden, um Tabellen, Spalten, gespeicherte Prozeduren, Schlüssel und Indizes programmatisch zu entdecken. Sie helfen Ihnen, datenbasierte Anwendungen zu erstellen, die sich zur Laufzeit an das Datenbankschema anpassen, wie Migrationstools, Codegeneratoren oder Admin-Dashboards.

Method ODBC-Funktion Rücklieferungen Wann verwenden?
tables() SQLTables Tabelle und Ansichtsinformationen. Inventardatenbanken. Validiere die Existenz der Tabelle vor Abfragen.
columns() SQLColumns Spaltendetails. DDL generieren, dynamische Abfragen erstellen oder Spalten auf Code abbilden.
procedures() SQLProcedures Gespeicherte Prozedurinformationen. Entdecken Sie verfügbare APIs. Erzeugen Sie Wrapper für Prozeduraufrufe.
primaryKeys() SQLPrimaryKeys Primärschlüsselspalten. Identifizieren Sie eindeutige Zeilenkennungen für UPDATE/DELETE Operationen.
foreignKeys() SQLForeignKeys Fremdschlüssel-Beziehungen. Kartiere Tabellenbeziehungen, bestimme die Löschreihenfolge für Reinigungsskripte.
statistics() 'SQLStatistics' Index- und Statistikinformationen. Überprüfen Sie die Indexabdeckung für Performance-Tuning.
rowIdColumns() SQLSpecialColumns (ROWID) Spalten für eindeutige Zeilenkennung. Finde die besten Spalten, um bestimmte Zeilen zu identifizieren.
rowVerColumns() SQLSpecialColumns (ROWVER) Spalten für die Zeilenversion. Implementieren Sie die optimistische Parallelitätssteuerung (gleichzeitige Änderungen erkennen).
getTypeInfo() SQLGetTypeInfo Datentypinformationen. Entdecken Sie unterstützte Typen für plattformübergreifende Kompatibilität.

Jede Methode gibt einen Cursor zurück, den du iterieren kannst, um auf die Ergebnisse zuzugreifen.

Tables

Listen Sie Tabellen und Ansichten in der Datenbank auf:

cursor = conn.cursor()

# List all tables
for row in cursor.tables():
    print(f"{row.table_schem}.{row.table_name} ({row.table_type})")

# Filter by name (supports wildcards % and _)
for row in cursor.tables(table="Product%"):
    print(row.table_name)

# Filter by schema
for row in cursor.tables(schema="Sales"):
    print(row.table_name)

# Filter by type
for row in cursor.tables(tableType="TABLE"):  # Excludes views
    print(row.table_name)

tables()-Parameter

Die folgenden Parameter steuern die Tabellenerkennung:

Parameter Beschreibung
table Tabellennamen-Muster (Supports % und _ Wildcards).
catalog Name des Katalogs (Datenbank).
schema Schema-Namensmuster.
tableType Filtern Sie nach Typ: TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, , . SYNONYM

tables()-Ergebnisspalten

Die Methode tables() liefert für jede Tabelle oder Ansicht folgende Spalten zurück:

Column Beschreibung
table_cat Name des Katalogs (Datenbank).
table_schem Name des Schemas.
table_name Der Name der Tabelle oder Ansicht.
table_type TABLE, VIEW, SYSTEM TABLE, , GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, . SYNONYM
remarks Beschreibung oder Kommentare.

Prüfe, ob eine Tabelle existiert

Überprüfen Sie, dass eine Tabelle existiert, bevor Sie sie abfragen:

if cursor.tables(table="Product", schema="Production").fetchone():
    print("Product table exists")
else:
    print("Product table not found")

Columns

Spalteninformationen für Tabellen abrufen:

# All columns in a table
for row in cursor.columns(table="Product", schema="Production"):
    print(f"{row.column_name}: {row.type_name}({row.column_size})")
    print(f"  Nullable: {row.nullable}, Position: {row.ordinal_position}")

# Filter by column name
for row in cursor.columns(table="Product", schema="Production", column="List%"):
    print(row.column_name)

Parameter von columns()

Filter zum Verfeinern der Erkennung von Spalten:

Parameter Beschreibung
table Muster für Tabellennamen.
catalog Name des Katalogs (Datenbank).
schema Schema-Namensmuster.
column Spaltennamen-Muster.

columns() Ergebnisspalten

Die Methode columns() liefert detaillierte Informationen zu jeder Spalte:

Column Beschreibung
table_cat, table_schem, table_name Standortkennzeichen.
column_name Spaltenname.
data_type SQL-Datentyp-Code.
type_name Datentypname (zum Beispiel varchar, ). int
column_size Maximale Länge oder Präzision.
buffer_length Puffergröße für Übertragungen.
decimal_digits Skalieren Sie für numerische Typen.
nullable 0 für NICHT NULL, 1 für nullable.
column_def Standardwert.
ordinal_position Spaltenposition (beginnend bei 1).
is_nullable "YES" oder "NO".

Gespeicherte Prozeduren

Entdecken Sie gespeicherte Verfahren:

# List all procedures
for row in cursor.procedures():
    print(f"{row.procedure_schem}.{row.procedure_name}")

# Filter by name pattern
for row in cursor.procedures(procedure="Get%"):
    print(row.procedure_name)

Verfahren()-Parameter

Filtern Sie gespeicherte Prozeduren nach Namen oder Schema:

Parameter Beschreibung
procedure Namensmuster der Prozedur.
catalog Name des Katalogs (Datenbank).
schema Schema-Namensmuster.

Ergebnisspalten von procedures()

Die Methode procedures() liefert Metadaten für jedes gespeicherte Verfahren zurück:

Column Beschreibung
procedure_cat, procedure_schem Standortkennzeichen.
procedure_name Der Name der Prozedur.
num_input_params Anzahl der Eingangsparameter.
num_output_params Anzahl der Ausgangsparameter.
num_result_sets Anzahl der Ergebnissätze.
remarks Description.
procedure_type Typindikator.

Primärschlüssel

Rufen Sie die Primärschlüsselspalten einer Tabelle ab:

for row in cursor.primaryKeys(table="Product", schema="Production"):
    print(f"PK column: {row.column_name} (position {row.key_seq})")
    print(f"Constraint name: {row.pk_name}")

primaryKeys()-Parameter

Parameter zum Abruf von primären Schlüsselinformationen:

Parameter Beschreibung
table Tabellenname (erforderlich).
catalog Name des Katalogs (Datenbank).
schema Name des Schemas.

primärKeys()-Ergebnisspalten

Die Methode primaryKeys() liefert folgende Informationen:

Column Beschreibung
table_cat, table_schem, table_name Standortkennzeichen.
column_name Spalte im Primärschlüssel.
key_seq Position in Mehrspalten-Taste (1-basiert).
pk_name Name der Primärschlüssel-Einschränkung.

Fremdschlüssel

Entdecken Sie Fremdschlüsselbeziehungen:

# Foreign keys from a table (outbound references)
for row in cursor.foreignKeys(table="SalesOrderDetail", schema="Sales"):
    print(f"FK {row.fk_name}:")
    print(f"  {row.fktable_name}.{row.fkcolumn_name}")
    print(f"  -> {row.pktable_name}.{row.pkcolumn_name}")

# Foreign keys to a table (inbound references)
for row in cursor.foreignKeys(foreignTable="Product", foreignSchema="Production"):
    print(f"{row.fktable_name} references Product")

foreignKeys()-Parameter

Spezifizieren Sie Primärschlüssel- oder Fremdschlüsseltabellen, um Zusammenhänge zu entdecken:

Parameter Beschreibung
table Name der Primärschlüsseltabelle.
catalog Primärschlüsselkatalog.
schema Primärschlüssel-Schema.
foreignTable Name der Fremdschlüsseltabelle.
foreignCatalog Fremdschlüsselkatalog.
foreignSchema Fremdschlüssel-Schema.

foreignKeys()-Ergebnisspalten

Die Methode foreignKeys() liefert folgende Spalten zurück, die Beziehungen beschreiben:

Column Beschreibung
pktable_cat, pktable_schem, pktable_name Referenzierte (primäre) Tabelle.
pkcolumn_name Referenzierte Spalte.
fktable_cat, fktable_schem, fktable_name Verweis auf (fremde) Tabelle.
fkcolumn_name Referenzspalte.
key_seq Position im Mehrspaltenschlüssel.
update_rule Aktion für UPDATE.
delete_rule Aktion auf DELETE.
fk_name Name der Fremdschlüsselbeschränkung.
pk_name Name der Primärschlüssel-Einschränkung.

Indizes und Statistiken

Erhalten Sie Indexinformationen für eine Tabelle:

# All indexes on a table
for row in cursor.statistics(table="Product", schema="Production"):
    if row.index_name:  # Skip table statistics row
        print(f"Index: {row.index_name}")
        print(f"  Column: {row.column_name} (position {row.ordinal_position})")
        print(f"  Unique: {not row.non_unique}")

# Only unique indexes
for row in cursor.statistics(table="Product", schema="Production", unique=True):
    print(f"Unique index: {row.index_name}")

statistik()-Parameter

Konfigurieren Sie die Indexerkennung mit diesen Filtern:

Parameter Vorgabe Beschreibung
table (erforderlich) Tabellenname.
catalog Nichts Name des Katalogs (Datenbank).
schema Nichts Schemaname.
unique False Geben Sie nur eindeutige Indizes zurück.
quick True Überspringe teure Kardinalitäts- und Seitenabrufe.

Ergebnisspalten von statistics()

Die Methode statistics() liefert Index- und Statistikinformationen:

Column Beschreibung
table_cat, table_schem, table_name Standortkennzeichen.
non_unique 0 für eindeutig, 1 für nicht-eindeutig.
index_name Name des Index.
type Index-Typ.
ordinal_position Spaltenposition im Index.
column_name Spaltenname.
asc_or_desc A für aufsteigend, D für absteigend.
cardinality Schätzung der Zeilenanzahl.
pages Seitenanzahl.

Zeilen-Identifikator-Spalten

Finden Sie Spalten, die eine Zeile eindeutig identifizieren:

for row in cursor.rowIdColumns(table="Product", schema="Production"):
    print(f"Row ID column: {row.column_name} ({row.type_name})")

Diese Methode liefert die beste Spaltenmenge zurück, um eine Zeile eindeutig zu identifizieren, die entweder der Primärschlüssel oder ein eindeutiger Index sein kann.

Spalten der Zeilenversion

Finden Sie Spalten, die automatisch aktualisiert werden, wenn sich ein Zeilenwert ändert. Verwenden Sie Zeilenversionsspalten für optimistische Nebenläufigkeitskontrolle, bei der Sie die Version einer Zeile lesen, Änderungen vornehmen und dann überprüfen, ob die aktuelle Zeilenversion gleich ist, bevor Sie schreiben:

for row in cursor.rowVerColumns(table="Product", schema="Production"):
    print(f"Version column: {row.column_name}")

Das Ergebnis umfasst typischerweise rowversion/timestamp Spalten, die für optimistische Nebenläufigkeit verwendet werden.

Datentypinformationen

Erhalten Sie Informationen zu unterstützten SQL-Datentypen:

# All supported types
for row in cursor.getTypeInfo():
    print(f"{row.type_name}: {row.data_type}")
    print(f"  Max size: {row.column_size}")
    print(f"  Nullable: {row.nullable}")

# Specific type
for row in cursor.getTypeInfo(sqlType=mssql_python.SQL_VARCHAR):
    print(f"VARCHAR max size: {row.column_size}")

getTypeInfo()-Parameter

Optionale Parameter zum Filtern unterstützter SQL-Typen:

Parameter Beschreibung
sqlType SQL-Typkonstante (für alle Typen weglassen).

Sicherheitsüberlegungen

Caution

Diese Methoden legen Metadaten aus Datenbankschemata frei. Während die Methoden selbst sicher auszuführen sind, zeigen die zurückgegebenen Informationen deine Datenbankstruktur (Tabellennamen, Spaltennamen, Beziehungen, Datentypen).

  • Stellen Sie keine Rohmetadaten für unzuverlässige Nutzer frei.
  • Ergebnisse in Multitenant-Anwendungen bereinigen oder filtern.
  • Beschränke den Zugriff auf extern ausgerichtete Anwendungen.

Beispiel: Erstellen Sie einen Schema-Bericht

def describe_table(conn, table_name):
    """Generate a schema description for a table."""
    cursor = conn.cursor()
    
    print(f"\n=== {table_name} ===\n")
    
    # Columns
    print("Columns:")
    for col in cursor.columns(table=table_name):
        nullable = "NULL" if col.nullable else "NOT NULL"
        print(f"  {col.column_name}: {col.type_name}({col.column_size}) {nullable}")
    
    # Primary key
    print("\nPrimary Key:")
    pk_cols = cursor.primaryKeys(table=table_name).fetchall()
    if pk_cols:
        pk_names = ", ".join(row.column_name for row in pk_cols)
        print(f"  {pk_cols[0].pk_name}: ({pk_names})")
    else:
        print("  (none)")
    
    # Foreign keys
    print("\nForeign Keys:")
    for fk in cursor.foreignKeys(table=table_name):
        print(f"  {fk.fk_name}: {fk.fkcolumn_name} -> {fk.pktable_name}.{fk.pkcolumn_name}")
    
    # Indexes
    print("\nIndexes:")
    for idx in cursor.statistics(table=table_name):
        if idx.index_name:
            unique = "UNIQUE " if not idx.non_unique else ""
            print(f"  {unique}{idx.index_name}: {idx.column_name}")

# Usage
describe_table(conn, "Product")