Files
romm/backend/utils/database.py
Georges-Antoine Assi 8e5d4cdcb5 disable pyright
2025-01-26 11:29:33 -05:00

48 lines
1.5 KiB
Python

from typing import Any
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql as sa_pg
from sqlalchemy.orm import Session
from sqlalchemy.sql import ColumnElement, func
def CustomJSON(**kwargs: Any) -> sa.JSON:
"""Custom SQLAlchemy JSON type that uses JSONB on PostgreSQL."""
return sa.JSON(**kwargs).with_variant(sa_pg.JSONB(**kwargs), "postgresql")
def is_postgresql(conn: sa.Connection) -> bool:
return conn.engine.name == "postgresql"
def json_array_contains_value(
column: sa.Column, value: Any, *, session: Session
) -> ColumnElement:
"""Check if a JSON array column contains a single value."""
conn = session.get_bind()
if is_postgresql(conn):
# In PostgreSQL, string values can be checked for containment using the `?` operator.
# For other types, we use the `@>` operator.
if isinstance(value, str):
return sa.type_coerce(column, sa_pg.JSONB).has_key(value)
return sa.type_coerce(column, sa_pg.JSONB).contains(
func.cast(value, sa_pg.JSONB)
)
return func.json_contains(column, value)
def safe_float(value: Any, default: float = 0.0) -> float:
"""Safely convert a value to float, returning default if conversion fails."""
try:
return float(value)
except (ValueError, TypeError):
return default
def safe_int(value: Any, default: int = 0) -> int:
"""Safely convert a value to int, returning default if conversion fails."""
try:
return int(value)
except (ValueError, TypeError):
return default