Files

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