mssql-pythonカーソルクラスは、ODBCカタログ関数にマッピングされる9つのメタデータメソッドを提供します。 これらの手法を使って、テーブル、カラム、ストアドプロシージャ、キー、インデックスをプログラム的に発見できます。 彼らは、マイグレーションツール、コードジェネレーター、管理ダッシュボードなど、ランタイムでデータベーススキーマに適応するデータ駆動型アプリケーションの開発を支援します。
| Method | ODBC関数 | 返品 | いつ使用するか |
|---|---|---|---|
tables() |
SQLTables | テーブルとビュー情報。 | 在庫データベース。 クエリの前にテーブルの存在を検証してください。 |
columns() |
SQLColumns | コラムの詳細。 | DDLを生成したり、動的なクエリを作成したり、列をコードにマッピングしたりできます。 |
procedures() |
SQLProcedures | ストアドプロシージャ情報。 | 利用可能なAPIを発見しましょう。 プロシージャ呼び出しラッパーを生成します。 |
primaryKeys() |
SQLPrimaryKeys | 主キー列。 | UPDATE/DELETE操作のための一意な行識別子を特定します。 |
foreignKeys() |
SQLForeignKeys | 外部キー リレーションシップ。 | マップテーブルの関係を管理し、クリーンアップスクリプトの削除順を決定します。 |
statistics() |
SQLStatistics | 索引および統計情報。 | パフォーマンス調整のためにインデックスカバレッジを確認してください。 |
rowIdColumns() |
SQLSpecialColumns (ROWID) | 一意の行識別子列。 | 特定の行を特定するのに最適な列を見つけましょう。 |
rowVerColumns() |
SQLSpecialColumns (ROWVER) | 行バージョン列。 | 楽的並行性(同時修正の検出)を実装します。 |
getTypeInfo() |
SQLGetTypeInfo | データ型情報。 | クロスプラットフォーム互換性のためにサポートされているタイプを発見。 |
各メソッドはカーソルを返し、結果にアクセスするために反復処理できます。
Tables
データベース内のテーブルとビューのリスト:
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() パラメータ
以下のパラメータはテーブルの発見を制御します:
| パラメーター | 説明 |
|---|---|
table |
テーブル名パターン( % および _ ワイルドカード対応)。 |
catalog |
カタログ(データベース)名。 |
schema |
スキーマ名パターン。 |
tableType |
タイプ別フィルター: TABLE、 VIEW、 SYSTEM TABLE、 GLOBAL TEMPORARY、 LOCAL TEMPORARY、 ALIAS、 SYNONYM。 |
テーブル() 結果列
tables()メソッドは各テーブルまたはビューごとに以下の列を返します:
| Column | 説明 |
|---|---|
table_cat |
カタログ(データベース)名。 |
table_schem |
スキーマ名。 |
table_name |
テーブルまたはビューの名前。 |
table_type |
TABLE、 VIEW、 SYSTEM TABLE、 GLOBAL TEMPORARY、 LOCAL TEMPORARY、 ALIAS、 SYNONYM。 |
remarks |
説明やコメント。 |
テーブルが存在するかどうか確認してください
クエリする前にテーブルの存在を必ず確認してください:
if cursor.tables(table="Product", schema="Production").fetchone():
print("Product table exists")
else:
print("Product table not found")
列
テーブルの列情報を取得する:
# 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)
columns() パラメータ
カラム発見を精準化するためのフィルター:
| パラメーター | 説明 |
|---|---|
table |
テーブル名パターン。 |
catalog |
カタログ(データベース)名。 |
schema |
スキーマ名パターン。 |
column |
列名パターン。 |
columns() の結果列
columns()メソッドは各列の詳細情報を返します:
| Column | 説明 |
|---|---|
table_cat、table_schem、table_name |
ロケーション識別子。 |
column_name |
列名。 |
data_type |
SQLデータ型コード。 |
type_name |
データ型名(例: varchar、 int)。 |
column_size |
最大の長さまたは精度。 |
buffer_length |
転送用のバッファサイズ。 |
decimal_digits |
数値タイプのためのスケール。 |
nullable |
0 NOT NULLの場合は 1 、nullableは。 |
column_def |
既定値。 |
ordinal_position |
列の位置(1ベース)。 |
is_nullable |
"YES" または "NO"。 |
ストアド プロシージャ
ストアド プロシージャを確認する:
# 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)
procedure() パラメータ
ストアドプロシージャを名前またはスキーマでフィルタリングする:
| パラメーター | 説明 |
|---|---|
procedure |
プロシージャ名のパターン。 |
catalog |
カタログ(データベース)名。 |
schema |
スキーマ名パターン。 |
procedure() 結果列
procedures()メソッドは各ストアドプロシージャのメタデータを返します:
| Column | 説明 |
|---|---|
procedure_cat、procedure_schem |
ロケーション識別子。 |
procedure_name |
プロシージャ名。 |
num_input_params |
入力パラメータの数。 |
num_output_params |
出力パラメータの数。 |
num_result_sets |
結果セットの数。 |
remarks |
Description. |
procedure_type |
タイプインジケーター。 |
主キー
表の主キー列を取得する:
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() パラメータ
主キー情報を取得するパラメータ:
| パラメーター | 説明 |
|---|---|
table |
テーブル名(必須)。 |
catalog |
カタログ(データベース)名。 |
schema |
スキーマ名。 |
primaryKeys() 結果列
primaryKeys()メソッドは以下の情報を返します。
| Column | 説明 |
|---|---|
table_cat、table_schem、table_name |
ロケーション識別子。 |
column_name |
主キーの列。 |
key_seq |
多列キー(1ベース)での位置。 |
pk_name |
プライマリキー制約名。 |
外部キー
外国の主要な関係を発見する:
# 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() パラメータ
関係を発見するために主鍵または外部鍵テーブルを指定する:
| パラメーター | 説明 |
|---|---|
table |
主キーテーブル名。 |
catalog |
主キーカタログ |
schema |
プライマリキースキーマ。 |
foreignTable |
外部キー テーブル名。 |
foreignCatalog |
外国鍵カタログ。 |
foreignSchema |
外部鍵スキーマ。 |
foreignKeys() 結果列
foreignKeys()メソッドは関係性を表す以下の列を返します。
| Column | 説明 |
|---|---|
pktable_cat、pktable_schem、pktable_name |
参照された(プライマリ)テーブル。 |
pkcolumn_name |
参照される列。 |
fktable_cat、fktable_schem、fktable_name |
(外国の)表を参照しています。 |
fkcolumn_name |
参照欄。 |
key_seq |
複数列キー内の位置。 |
update_rule |
UPDATE に対する操作。 |
delete_rule |
DELETE に対するアクション。 |
fk_name |
外部キー制約名。 |
pk_name |
プライマリキー制約名。 |
指数と統計
表のインデックス情報を得る:
# 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}")
statistics() パラメータ
以下のフィルターでインデックスディスカバリを設定します:
| パラメーター | Default | 説明 |
|---|---|---|
table |
("必須") | テーブル名。 |
catalog |
なし | カタログ(データベース)名。 |
schema |
なし | スキーマ名。 |
unique |
False | ユニークなインデックスのみを返します。 |
quick |
True | コストの高いカーディナリティやページ数の取得をスキップします。 |
statistics() の結果列
statistics()メソッドはインデックスおよび統計情報を返します:
| Column | 説明 |
|---|---|
table_cat、table_schem、table_name |
ロケーション識別子。 |
non_unique |
0 は一意、1 は非一意。 |
index_name |
インデックス名。 |
type |
インデックスタイプ。 |
ordinal_position |
インデックス内の列の位置。 |
column_name |
列名。 |
asc_or_desc |
昇順の場合は A、降順の場合は D。 |
cardinality |
行数の推定値。 |
pages |
ページ数。 |
行識別子列
行を一意に識別する列を見つけてください:
for row in cursor.rowIdColumns(table="Product", schema="Production"):
print(f"Row ID column: {row.column_name} ({row.type_name})")
このメソッドは、主キーや一意インデックスのいずれかの行を一意に識別するための最良の列集合を返します。
行バージョン列
行の値が変わったときに自動的に更新される列を見つけてください。 行バージョンの列を使って楽観的な並行管理を行いましょう。行のバージョンを読み取り、変更を加え、現在の行バージョンが同じかどうかを確認してから書き込む方法です:
for row in cursor.rowVerColumns(table="Product", schema="Production"):
print(f"Version column: {row.column_name}")
その結果には通常、楽観的同時実行制御に使用される rowversion/timestamp 列が含まれます。
データ型情報
サポートされているSQLデータ型に関する情報を得る:
# 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() パラメーター
サポートするSQL型をフィルタリングするためのオプションパラメータ:
| パラメーター | 説明 |
|---|---|
sqlType |
SQL 型定数(すべての型で省略) |
セキュリティに関する考慮事項
Caution
これらの手法はデータベーススキーマのメタデータを公開します。 メソッド自体は安全に実行できますが、返される情報はデータベース構造(テーブル名、列名、リレーションシップ、データ型)を明らかにします。
- 生のメタデータを信頼できないユーザーに公開しないでください。
- サニタイズやフィルタリングはマルチテナントアプリケーションにつながります。
- 外部向けアプリケーションのアクセスを制限しましょう。
例:スキーマレポートを生成する
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")