import typing import uuid from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from server.db.cellxgene_orm import Base, CellxGeneDataset, CellxGeneUser class DbUtils: def __init__(self, database_uri: str = "postgresql://postgres:test_pw@localhost:5432"): self.session = DBSessionMaker(database_uri).session() self.engine = self.session.get_bind() def get(self, table: Base, entity_id: typing.Union[str, typing.Tuple[str]]) -> typing.Union[Base, None]: """ Query a table row by its primary key :param table: SQLAlchemy Table to query :param entity_id: Primary key of desired row :return: SQLAlchemy Table object, None if not found """ return self.session.query(table).get(entity_id) def query(self, table_args: typing.List[Base], filter_args: typing.List[bool] = None) -> typing.List[Base]: """ Query the database using the current DB session :param table_args: List of SQLAlchemy Tables to query/join :param filter_args: List of SQLAlchemy filter conditions :return: List of SQLAlchemy query response objects """ return ( self.session.query(*table_args).filter(*filter_args).all() if filter_args else self.session.query(*table_args).all() ) def query_for_most_recent(self, table: Base, filter_args: typing.List[bool] = None) -> Base: try: return self.session.query(table).filter(*filter_args).order_by(table.created_at.desc()).limit(1).all()[0] except IndexError: return None def get_or_create_dataset(self, dataset_name): try: dataset_id = self.query(table_args=[CellxGeneDataset], filter_args=[CellxGeneDataset.name == dataset_name])[ 0 ].id except IndexError: dataset_id = uuid.uuid4() dataset = CellxGeneDataset(id=dataset_id, name=dataset_name) self.session.add(dataset) self.session.commit() return str(dataset_id) def get_or_create_user(self, user_id): try: user_id = self.query(table_args=[CellxGeneUser], filter_args=[CellxGeneUser.id == user_id])[0].id except IndexError: user = CellxGeneUser(id=user_id) self.session.add(user) self.session.commit() return str(user_id) class DBSessionMaker: def __init__(self, database_uri): self.engine = create_engine(database_uri, connect_args={"connect_timeout": 5}) self.session_maker = sessionmaker(bind=self.engine) def session(self, **kwargs): return self.session_maker(**kwargs)