Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhanced MSSQL metadata collection to include foreign keys and table row counts. #106

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion odd-collector/odd_collector/adapters/mssql/mappers/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ def map_table(table: Table, generator: MssqlGenerator):
oddrn = generator.get_oddrn_by_path("tables")

map_col = partial(map_column, oddrn_generator=generator, parent_oddrn_path="tables")
dataset = DataSet(field_list=lmap(map_col, table.columns))
dataset = DataSet(
rows_number=table.table_rows, field_list=lmap(map_col, table.columns)
)

return DataEntity(
oddrn=oddrn,
Expand Down
2 changes: 2 additions & 0 deletions odd-collector/odd_collector/adapters/mssql/models/column.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class Column:
column_default: str
is_nullable: bool
is_primary_key: bool
is_foreign_key: bool
data_type: str
character_maximum_length: int
character_octet_length: int
Expand All @@ -37,3 +38,4 @@ def odd_metadata(self) -> Dict[str, str]:

def __post_init__(self):
self.is_primary_key = bool(self.is_primary_key)
self.is_foreign_key = bool(self.is_foreign_key)
2 changes: 2 additions & 0 deletions odd-collector/odd_collector/adapters/mssql/models/table.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import asdict, dataclass, field
from typing import Optional

from funcy import omit
from odd_collector.adapters.mssql.models.column import Column
Expand All @@ -11,6 +12,7 @@ class Table:
table_schema: str
table_name: str
table_type: str
table_rows: Optional[int] = None
columns: list[Column] = field(default_factory=list)

@property
Expand Down
42 changes: 35 additions & 7 deletions odd-collector/odd_collector/adapters/mssql/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,26 @@ def get_columns_for(self, database: str, schema: str, name: str) -> list[Column]

TABLES_QUERY: str = """
SELECT
table_catalog,
table_schema,
table_name,
table_type
FROM information_schema.tables
WHERE table_type != 'VIEW'
ORDER BY table_catalog, table_schema, table_name;"""
t.table_catalog,
t.table_schema,
t.table_name,
t.table_type,
SUM(p.rows) AS table_rows
FROM information_schema.tables t
JOIN sys.schemas s ON t.table_schema = s.name
JOIN sys.objects o ON t.table_name = o.name AND o.schema_id = s.schema_id
JOIN sys.partitions p ON o.object_id = p.object_id
WHERE t.table_type = 'BASE TABLE' AND p.index_id IN (0, 1)
GROUP BY
t.table_catalog,
t.table_schema,
t.table_name,
t.table_type
ORDER BY
t.table_catalog,
t.table_schema,
t.table_name;
"""

COLUMNS_QUERY: str = """
WITH primary_keys as (
Expand All @@ -41,6 +54,12 @@ def get_columns_for(self, database: str, schema: str, name: str) -> list[Column]
INNER JOIN information_schema.key_column_usage AS KU
ON TC.constraint_name = KU.constraint_name
AND TC.constraint_type = 'PRIMARY KEY'
),
foreign_keys AS (
SELECT CU.table_catalog, CU.table_schema, CU.table_name, CU.column_name
FROM information_schema.referential_constraints AS RC
INNER JOIN information_schema.constraint_column_usage AS CU
ON RC.constraint_name = CU.constraint_name
)
SELECT
C.table_catalog,
Expand All @@ -54,6 +73,10 @@ def get_columns_for(self, database: str, schema: str, name: str) -> list[Column]
WHEN PK.column_name IS NOT NULL THEN 1
ELSE 0
END AS is_primary_key,
CASE
WHEN FK.column_name IS NOT NULL THEN 1
ELSE 0
END AS is_foreign_key,
C.data_type,
C.character_maximum_length,
C.character_octet_length,
Expand All @@ -76,6 +99,11 @@ def get_columns_for(self, database: str, schema: str, name: str) -> list[Column]
AND C.table_schema = PK.table_schema
AND C.table_name = PK.table_name
AND C.column_name = PK.column_name
LEFT JOIN foreign_keys AS FK
ON C.table_catalog = FK.table_catalog
AND C.table_schema = FK.table_schema
AND C.table_name = FK.table_name
AND C.column_name = FK.column_name
ORDER BY C.table_catalog, C.table_schema, C.table_name, C.ordinal_position
"""

Expand Down
Loading