Objevování schématu pomocí mssql-python

Kurzorová třída mssql-python poskytuje devět metadatových metod, které se mapují na katalogové funkce ODBC. Použijte tyto metody k programovému objevování tabulek, sloupců, uložených procedur, klíčů a indexů. Pomáhají vám vytvářet datově orientované aplikace, které se přizpůsobují databázovému schématu za běhu, například nástroje pro migraci, generátory kódu nebo administrátorské dashboardy.

Metoda Funkce ODBC Returns Kdy ho použít
tables() SQLTables Tabulka a informace o zobrazení. Databáze inventáře. Ověřte existenci tabulky před dotazy.
columns() SQLColumns Podrobnosti o sloupcích. Generujte DDL, vytvářejte dynamické dotazy nebo mapujte sloupce na kód.
procedures() SQLProcedures Informace o uložených procedurách. Objevte dostupná API. Generujte obálky volání procedur.
primaryKeys() SQLPrimaryKeys Hlavní klíčové sloupce. Identifikujte jedinečné identifikátory řádků pro UPDATE/DELETE operace.
foreignKeys() SQLForeignKeys Relace cizích klíčů. Mapujte vztahy mezi tabulkami, určujte pořadí mazání u skriptů pro čištění.
statistics() SQLStatistics Informace o indexu a statistikách. Ověřte pokrytí indexu pro ladění výkonu.
rowIdColumns() SQLSpecialColumns (ROWID) Sloupce s unikátními identifikátory řádků. Najděte nejlepší sloupce pro identifikaci konkrétních řádků.
rowVerColumns() SQLSpecialColumns (ROWVER) Sloupce verze řádku. Implementujte optimistickou souběžnost (detekujte souběžné modifikace).
getTypeInfo() SQLGetTypeInfo Informace o datovém typu Objevte podporované typy pro kompatibilitu napříč platformami.

Každá metoda vrací kurzor, který můžete iterovat pro přístup k výsledkům.

Tables

Seznam tabulek a pohledů v databázi:

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)

Parametry funkce tables()

Následující parametry řídí zjišťování tabulek:

Parameter Popis
table Vzor názvu tabulky (podporuje zástupné znaky % a _).
catalog Název katalogu (databáze).
schema Vzor názvu schématu.
tableType Filtrujte podle typu: TABLE, VIEW, , SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL TEMPORARY, ALIAS, . SYNONYM

tabulky() sloupce výsledků

Metoda tables() vrací následující sloupce pro každou tabulku nebo pohled:

Column Popis
table_cat Název katalogu (databáze).
table_schem Název schématu
table_name Název tabulky nebo zobrazení.
table_type TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, , LOCAL TEMPORARY, ALIAS. SYNONYM
remarks Popis nebo komentáře.

Zkontrolujte, zda existuje tabulka

Před jejím dotazem ověřte, že tabulka existuje:

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

Columns

Získejte informace o sloupcích pro tabulky:

# 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)

parametry columns()

Filtry pro zpřesnění objevování sloupců:

Parameter Popis
table Vzorec názvu tabulky.
catalog Název katalogu (databáze).
schema Vzor názvů schématu.
column Vzor názvů sloupců.

columns() sloupce výsledků

Metoda vrací columns() podrobné informace o každém sloupci:

Column Popis
table_cat, table_schem, table_name Identifikátory polohy.
column_name Název sloupce
data_type Kód datového typu SQL.
type_name Název datového typu (například varchar, int).
column_size Maximální délka nebo přesnost.
buffer_length Velikost bufferu pro přenosy.
decimal_digits Škála pro číselné typy.
nullable 0 pro NOT NULL, 1 pro hodnotu null.
column_def Výchozí hodnota.
ordinal_position Pozice sloupce (indexováno od 1).
is_nullable "YES" nebo "NO".

Uložené procedury

Objevte uložené postupy:

# 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)

parametry procedur()

Filtrujte uložené procedury podle názvu nebo schématu:

Parameter Popis
procedure Vzor názvu procedury.
catalog Název katalogu (databáze).
schema Vzor názvu schématu.

sloupce výsledku procedures()

Metoda procedures() vrací metadata pro každou uloženou proceduru:

Column Popis
procedure_cat, procedure_schem Identifikátory polohy.
procedure_name Název procedury
num_input_params Počet vstupních parametrů.
num_output_params Počet výstupních parametrů.
num_result_sets Počet sad výsledků.
remarks Description.
procedure_type Indikátor typu.

Primární klíče

Získejte hlavní klíčové sloupce pro tabulku:

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}")

parametry metody primaryKeys()

Parametry pro získání informací o primárním klíči:

Parameter Popis
table Název tabulky (povinný).
catalog Název katalogu (databáze).
schema Název schématu

sloupce výsledků primaryKeys()

Metoda primaryKeys() vrací následující informace:

Column Popis
table_cat, table_schem, table_name Identifikátory polohy.
column_name Sloupec v primárním klíči.
key_seq Pozice ve vícesloupcovém klíči (číslováno od 1).
pk_name Název omezení primárního klíče.

Cizí klíče

Objevte zahraniční klíčové vztahy:

# 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")

parametry foreignKeys()

Specifikujte tabulky primárních klíčů nebo cizích klíčů pro objevení vztahů:

Parameter Popis
table Název tabulky primárního klíče
catalog Katalog hlavních klíčů.
schema Schéma primárních klíčů.
foreignTable Název tabulky pro cizí klíč
foreignCatalog Katalog cizích klíčů.
foreignSchema Cizí klíčové schéma.

sloupce výsledků foreignKeys()

Metoda foreignKeys() vrací následující sloupce popisující vztahy:

Column Popis
pktable_cat, pktable_schem, pktable_name Referenční (primární) tabulka.
pkcolumn_name Odkazovaný sloupek.
fktable_cat, fktable_schem, fktable_name Odkazování na (cizí) tabulku.
fkcolumn_name Odkazující sloupek.
key_seq Pozice ve vícesloupcovém klíči.
update_rule Akce na UPDATE.
delete_rule Akce na DELETE.
fk_name Název cizího klíčového omezení.
pk_name Název omezení primárního klíče.

Rejstříky a statistiky

Získejte informace o indexu tabulky:

# 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}")

parametry funkce statistics()

Konfigurujte objevování indexů pomocí těchto filtrů:

Parameter Výchozí Popis
table (požadováno) Název tabulky
catalog Žádný Název katalogu (databáze).
schema Žádný Název schématu
unique Nepravda Vraťte pouze jedinečné indexy.
quick Pravdivé Přeskočte nákladné načítání kardinality a stránek.

sloupce výsledku funkce statistics()

Metoda statistics() vrací indexové a statistické informace:

Column Popis
table_cat, table_schem, table_name Identifikátory polohy.
non_unique 0 pro jedinečné, 1 pro nejedinečné.
index_name Název indexu.
type Typ indexu.
ordinal_position Pozice sloupce v indexu.
column_name Název sloupce
asc_or_desc A Na stoupání, D na sestup.
cardinality Odhad počtu řádků.
pages Počet stran.

Sloupce s identifikátory řádků

Najděte sloupce, které jednoznačně identifikují řádek:

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

Tato metoda vrací nejlepší sadu sloupců pro jednoznačnou identifikaci řádku, což může být primární klíč nebo jedinečný index.

Sloupce veršních verzí

Najděte sloupce, které se automaticky aktualizují při změně hodnoty řádku. Použijte sloupce s verzí řádku pro optimistické řízení souběžnosti, při kterém přečtete verzi řádku, provedete změny a potom před zápisem ověříte, že aktuální verze řádku je stejná:

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

Výsledek obvykle zahrnuje rowversion/timestamp sloupce používané pro optimistickou souběžnost.

Informace o datovém typu

Získejte informace o podporovaných SQL datových typech:

# 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}")

parametry metody getTypeInfo()

Volitelné parametry pro filtrování podporovaných SQL typů:

Parameter Popis
sqlType SQL typová konstanta (vynechat pro všechny typy).

Bezpečnostní aspekty

Caution

Tyto metody zveřejňují metadata databázového schématu. I když jsou metody samotné bezpečné k vykonání, vrácené informace odhalují strukturu vaší databáze (názvy tabulek, názvy sloupců, vztahy, datové typy).

  • Nezveřejňujte surová metadata nedůvěryhodným uživatelům.
  • Ošetřete nebo filtrujte výsledky ve víceklientských aplikacích.
  • Omezte přístup v aplikacích orientovaných zvenčí.

Příklad: Generujte report schématu

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")