69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
"""`sso_users` 表结构兼容工具。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from sqlalchemy import text
|
|
|
|
|
|
class SsoUserCompat:
|
|
"""兼容旧环境 `sso_users` 尚未完成租户字段迁移的场景。"""
|
|
|
|
_columns_cache: set[str] | None = None
|
|
|
|
@classmethod
|
|
async def get_columns(cls, session) -> set[str]:
|
|
if cls._columns_cache is not None:
|
|
return cls._columns_cache
|
|
|
|
rows = await session.execute(
|
|
text(
|
|
"""
|
|
SELECT column_name
|
|
FROM information_schema.columns
|
|
WHERE table_schema = current_schema()
|
|
AND table_name = 'sso_users'
|
|
"""
|
|
)
|
|
)
|
|
cls._columns_cache = {str(row[0]) for row in rows.fetchall()}
|
|
return cls._columns_cache
|
|
|
|
@staticmethod
|
|
def raw_optional_column(
|
|
columns: set[str],
|
|
*,
|
|
alias: str,
|
|
column: str,
|
|
pg_type: str = "varchar",
|
|
) -> str:
|
|
if column in columns:
|
|
return f"{alias}.{column}"
|
|
return f"NULL::{pg_type}"
|
|
|
|
@classmethod
|
|
def optional_column_as(
|
|
cls,
|
|
columns: set[str],
|
|
*,
|
|
alias: str,
|
|
column: str,
|
|
pg_type: str = "varchar",
|
|
output_alias: str | None = None,
|
|
) -> str:
|
|
expression = cls.raw_optional_column(columns, alias=alias, column=column, pg_type=pg_type)
|
|
return f"{expression} AS {output_alias or column}"
|
|
|
|
@classmethod
|
|
def optional_coalesce_as(
|
|
cls,
|
|
columns: set[str],
|
|
*,
|
|
alias: str,
|
|
column: str,
|
|
fallback_sql: str,
|
|
pg_type: str = "varchar",
|
|
output_alias: str | None = None,
|
|
) -> str:
|
|
expression = cls.raw_optional_column(columns, alias=alias, column=column, pg_type=pg_type)
|
|
return f"COALESCE({expression}, {fallback_sql}) AS {output_alias or column}"
|