Source code for nexusLIMS.tui.common.db_utils
"""
Database utilities for NexusLIMS TUI applications.
Provides common database query patterns.
"""
from typing import Any
from sqlmodel import Session, select
from nexusLIMS.db.models import Instrument, SessionLog
[docs]
def check_uniqueness(
session: Session,
model: type,
field_name: str,
value: Any,
exclude_pk: Any | None = None,
) -> bool:
"""
Check if a value is unique for a given field.
Parameters
----------
session : Session
Active database session
model : type
SQLModel model class (e.g., Instrument)
field_name : str
Field name to check (e.g., "api_url")
value : Any
Value to check for uniqueness
exclude_pk : Any | None
Primary key value to exclude (for edit operations)
Returns
-------
bool
True if unique, False if duplicate exists
Examples
--------
>>> from nexusLIMS.db.models import Instrument
>>> with get_db_session() as session:
... is_unique = check_uniqueness(
... session, Instrument, "api_url",
... "https://example.com/api/tools/?id=42"
... )
"""
# Skip check if value is None (for optional fields)
if value is None:
return True
# Build query
field = getattr(model, field_name)
statement = select(model).where(field == value)
# Exclude current record if editing
if exclude_pk is not None:
pk_field = getattr(model, model.__table__.primary_key.columns.keys()[0])
statement = statement.where(pk_field != exclude_pk)
# Check if any records exist
existing = session.exec(statement).first()
return existing is None
[docs]
def get_session_log_count(session: Session, instrument_pid: str) -> int:
"""
Get count of session_log entries for an instrument.
Useful for warning users before deleting an instrument with associated data.
Parameters
----------
session : Session
Active database session
instrument_pid : str
Instrument primary key
Returns
-------
int
Number of session_log entries
Examples
--------
>>> with get_db_session() as session:
... count = get_session_log_count(session, "FEI-Titan-TEM")
... if count > 0:
... print(f"Warning: {count} session logs will be orphaned")
"""
statement = select(SessionLog).where(SessionLog.instrument == instrument_pid)
results = session.exec(statement).all()
return len(results)
[docs]
def find_conflicting_instrument(
session: Session,
field_name: str,
value: Any,
exclude_pid: str | None = None,
) -> Instrument | None:
"""
Find an instrument that conflicts with a unique field value.
Parameters
----------
session : Session
Active database session
field_name : str
Unique field name (e.g., api_url)
value : Any
Value to search for
exclude_pid : str | None
Instrument PID to exclude (for edit operations)
Returns
-------
Instrument | None
Conflicting instrument, or None if no conflict
Examples
--------
>>> with get_db_session() as session:
... conflict = find_conflicting_instrument(
... session, "api_url", "https://example.com/api"
... )
... if conflict:
... print(f"Already used by {conflict.instrument_pid}")
"""
if value is None:
return None
field = getattr(Instrument, field_name)
statement = select(Instrument).where(field == value)
if exclude_pid is not None:
statement = statement.where(Instrument.instrument_pid != exclude_pid)
return session.exec(statement).first()