Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLAlchemy 2.0 #17778

Merged
merged 76 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
fa344f7
Upgrade SQLAlchemy to 2.0
jdavcs Dec 12, 2023
7510325
Remove RemovedIn20Warning from config
jdavcs Dec 19, 2023
61c463f
Update import path for DeclarativeMeta
jdavcs Jan 9, 2024
9d7ae1b
Move declaration of injected attrs into constructor
jdavcs Dec 12, 2023
03597bb
Apply Mapped/mapped_column to model definitions
jdavcs Dec 20, 2023
7c2a1a4
Add typing to JSON columns, fix related mypy errors
jdavcs Feb 2, 2024
1a26f75
Use correct type hints to define common model attrs
jdavcs Jan 19, 2024
00fc1ee
Start applying Mapped to relationship definitions in the model
jdavcs Jan 16, 2024
5c27fe1
Remove column declaration from HasTags parent class
jdavcs Jan 24, 2024
937292d
Fix SA2.0 error: wrap sql in text()
jdavcs Dec 19, 2023
3c4543b
Fix SA2.0 error: pass bind to create_all
jdavcs Dec 19, 2023
fb018c5
Fix SA2.0 error: use Row._mapping for keyed attribute access
jdavcs Dec 19, 2023
ecd6c36
Fix SA2.0 error: show password in url
jdavcs Dec 20, 2023
3aae92b
Fix SA2.0 error: use attribute_keyed_dict
jdavcs Jan 24, 2024
2254054
Fix SA2.0 error: make select stmt a subquery
jdavcs Jan 25, 2024
b3cef4f
Fix SA2.0 error: explicitly use subquery() for select-from argument
jdavcs Feb 7, 2024
72dcc40
Fix SA2.0 error: replase session.bind with session.get_bind()
jdavcs Feb 12, 2024
0e61d61
Fix SA2.0 error: joinedload does not take str args
jdavcs Feb 12, 2024
3c5c4f7
Fix use of table model attribute
jdavcs Jan 17, 2024
a747688
Fix bug: fix HistoryAudit model
jdavcs Jan 19, 2024
e3a695c
Fix bug: check if template.fields is not null before iterating
jdavcs Feb 5, 2024
6815239
Fix bug: call unique() on result, not select stmt
jdavcs Feb 9, 2024
c5b8b7e
Fix bug: do not pass subquery to in_
jdavcs Feb 9, 2024
cc87d06
Fix bug/typo: use select_from
jdavcs Feb 9, 2024
e3305a3
Fix bug: if using alias on ORM entity, use __table__ as valid FromClause
jdavcs Feb 9, 2024
7281000
Fix bug: HDAH model is not serializable (caught by mypy)
jdavcs Jan 25, 2024
4d325b1
Fix typing error: migrations.base
jdavcs Jan 23, 2024
79261dd
Fix typing error: managers.secured
jdavcs Jan 24, 2024
78aa970
Fix typing error: session type
jdavcs Jan 25, 2024
f1579e1
Fix typing error: use Session instead of scoped_session
jdavcs Feb 2, 2024
cae92b7
Fix typing error: sharable
jdavcs Feb 9, 2024
92199f3
Fix SA2.0 error: sqlalchemy exceptions import; minor mypy fix
jdavcs Feb 6, 2024
22266bf
Mypy: type-ignore: this is never SessionlessContext
jdavcs Jan 23, 2024
1a24935
Mypy: use verbose assignment to help mypy
jdavcs Jan 23, 2024
dc7b002
Mypy: add assert stmt
jdavcs Jan 23, 2024
9a3877f
Mypy: add assert to ensure seesion is not None
jdavcs Jan 24, 2024
527134e
Mypy: return 0 if no results
jdavcs Jan 24, 2024
511816e
Mypy: type-ignore: scoped_session vs. install_model_session
jdavcs Jan 24, 2024
92b9521
Mypy: refactor to one-liner
jdavcs Jan 25, 2024
92cf377
Mypy: add assert stmts where we know session returns an object
jdavcs Jan 25, 2024
85d54c6
Mypy: rename wfi_step > wfi_step_sq when it becomes a subquery
jdavcs Jan 25, 2024
d93d7e2
Job search refactor: factor out build_job_subquery
jdavcs Jan 26, 2024
fd1baee
Job search refactor: build_stmt_for_hda
jdavcs Jan 27, 2024
d47ec41
Job search refactor: build_stmt_for_ldda
jdavcs Jan 27, 2024
5d17b27
Job search refactor: build_stmt_for_hdca
jdavcs Jan 27, 2024
8afb02d
Job search refactor: build_stmt_for_dce
jdavcs Jan 27, 2024
4f17324
Job search refactor: rename query >> stmt
jdavcs Jan 27, 2024
cab3fda
Mypy: add anno for Lists; type-ignore for HDAs
jdavcs Jan 27, 2024
3ce1a75
Mypy: managers.histories
jdavcs Feb 2, 2024
2002076
Mypy: model.deferred
jdavcs Feb 2, 2024
58c35c2
Mypy: arg passed to template can be None
jdavcs Feb 5, 2024
dd6a8c0
Mypy: celery tasks
jdavcs Feb 5, 2024
a6162ed
Mypy: type-ignore hda attr-defined error
jdavcs Feb 6, 2024
82f8438
Convert visualization manager index query to SA Core
jdavcs Feb 6, 2024
3fb0c9c
Mypy: session is not none
jdavcs Feb 6, 2024
b146837
Mypy: type-ignore what requires more refactoring
jdavcs Feb 6, 2024
4255c15
Mypy: type-ignore hda, ldda attrs: need declarative mapping
jdavcs Feb 6, 2024
eb46a08
Mypy: type-ignores to handle late evaluation of relationship arguments
jdavcs Feb 7, 2024
f3740c6
Mypy: type-ignore column property assignments (type is correct)
jdavcs Feb 8, 2024
78a77d9
Mypy: typing errors, misc. fixes
jdavcs Feb 6, 2024
f9cebc6
Mypy: all statements are reachable
jdavcs Feb 12, 2024
3e5c46b
Mypy: need to map hda declaratively, then its parent is model.Base
jdavcs Feb 12, 2024
05a5b01
Fix typing errors: sharable, secured
jdavcs Feb 9, 2024
28fd6ad
Fix package mypy errors
jdavcs Feb 13, 2024
cc23a9d
Fix SA2.0 error: celery task
jdavcs Feb 13, 2024
6a800c0
Wrap call to ensure session is closed
jdavcs Feb 20, 2024
3c74f9d
Ensure session is closed on TS Registry load
jdavcs Feb 20, 2024
631b504
Fix SA2.0 error: list arg to select; mypy
jdavcs Feb 20, 2024
f52d35b
Use NullPool for sqlite engines
jdavcs Feb 23, 2024
2e0ec6f
Help mypy: job is never None
jdavcs Feb 28, 2024
dc2621b
Add Decimal to accpted types by util.nice_size()
jdavcs Mar 5, 2024
e35d017
Fix linting after rebase
jdavcs Mar 18, 2024
f07a6f2
Use model_dump_json() instead of deprecated json()
jdavcs Apr 2, 2024
a8f2f2c
Add AssociationProxy type, drop type-ignore
jdavcs Apr 2, 2024
1c4b114
Fix new bug: wrap raw sql in text()
jdavcs Apr 2, 2024
2c527d4
Fix new bug: incorrect type in calculate_disk_usage_per_objectstore
jdavcs Apr 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/galaxy/app_unittest_utils/galaxy_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def __init__(self, config=None, **kwargs) -> None:
self[ShortTermStorageMonitor] = sts_manager # type: ignore[type-abstract]
self[galaxy_scoped_session] = self.model.context
self.visualizations_registry = MockVisualizationsRegistry()
self.tag_handler = tags.GalaxyTagHandler(self.model.context)
self.tag_handler = tags.GalaxyTagHandler(self.model.session)
self[tags.GalaxyTagHandler] = self.tag_handler
self.quota_agent = quota.DatabaseQuotaAgent(self.model)
self.job_config = Bunch(
Expand Down
45 changes: 17 additions & 28 deletions lib/galaxy/celery/base_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
)
from sqlalchemy.dialects.postgresql import insert as ps_insert
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session

from galaxy.model import CeleryUserRateLimit
from galaxy.model.base import transaction
Expand Down Expand Up @@ -70,7 +69,7 @@ def __call__(self, task: Task, task_id, args, kwargs):

@abstractmethod
def calculate_task_start_time(
self, user_id: int, sa_session: Session, task_interval_secs: float, now: datetime.datetime
self, user_id: int, sa_session: galaxy_scoped_session, task_interval_secs: float, now: datetime.datetime
) -> datetime.datetime:
return now

Expand All @@ -81,38 +80,28 @@ class GalaxyTaskBeforeStartUserRateLimitPostgres(GalaxyTaskBeforeStartUserRateLi
We take advantage of efficiencies in its dialect.
"""

_update_stmt = (
update(CeleryUserRateLimit)
.where(CeleryUserRateLimit.user_id == bindparam("userid"))
.values(last_scheduled_time=text("greatest(last_scheduled_time + ':interval second', " ":now) "))
.returning(CeleryUserRateLimit.last_scheduled_time)
)

_insert_stmt = (
ps_insert(CeleryUserRateLimit)
.values(user_id=bindparam("userid"), last_scheduled_time=bindparam("now"))
.returning(CeleryUserRateLimit.last_scheduled_time)
)

_upsert_stmt = _insert_stmt.on_conflict_do_update(
index_elements=["user_id"], set_=dict(last_scheduled_time=bindparam("sched_time"))
)

def calculate_task_start_time( # type: ignore
self, user_id: int, sa_session: Session, task_interval_secs: float, now: datetime.datetime
self, user_id: int, sa_session: galaxy_scoped_session, task_interval_secs: float, now: datetime.datetime
) -> datetime.datetime:
with transaction(sa_session):
result = sa_session.execute(
self._update_stmt, {"userid": user_id, "interval": task_interval_secs, "now": now}
update_stmt = (
update(CeleryUserRateLimit)
.where(CeleryUserRateLimit.user_id == user_id)
.values(last_scheduled_time=text("greatest(last_scheduled_time + ':interval second', " ":now) "))
.returning(CeleryUserRateLimit.last_scheduled_time)
)
if result.rowcount == 0:
result = sa_session.execute(update_stmt, {"interval": task_interval_secs, "now": now}).all()
if not result:
sched_time = now + datetime.timedelta(seconds=task_interval_secs)
result = sa_session.execute(
self._upsert_stmt, {"userid": user_id, "now": now, "sched_time": sched_time}
upsert_stmt = (
ps_insert(CeleryUserRateLimit) # type:ignore[attr-defined]
.values(user_id=user_id, last_scheduled_time=now)
.returning(CeleryUserRateLimit.last_scheduled_time)
.on_conflict_do_update(index_elements=["user_id"], set_=dict(last_scheduled_time=sched_time))
)
for row in result:
return row[0]
result = sa_session.execute(upsert_stmt).all()
sa_session.commit()
return result[0][0]


class GalaxyTaskBeforeStartUserRateLimitStandard(GalaxyTaskBeforeStartUserRateLimit):
Expand All @@ -138,7 +127,7 @@ class GalaxyTaskBeforeStartUserRateLimitStandard(GalaxyTaskBeforeStartUserRateLi
)

def calculate_task_start_time(
self, user_id: int, sa_session: Session, task_interval_secs: float, now: datetime.datetime
self, user_id: int, sa_session: galaxy_scoped_session, task_interval_secs: float, now: datetime.datetime
) -> datetime.datetime:
last_scheduled_time = None
with transaction(sa_session):
Expand Down
5 changes: 4 additions & 1 deletion lib/galaxy/celery/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ def set_metadata(
try:
if overwrite:
hda_manager.overwrite_metadata(dataset_instance)
dataset_instance.datatype.set_meta(dataset_instance)
dataset_instance.datatype.set_meta(dataset_instance) # type:ignore [arg-type]
dataset_instance.set_peek()
# Reset SETTING_METADATA state so the dataset instance getter picks the dataset state
dataset_instance.set_metadata_success_state()
Expand Down Expand Up @@ -228,6 +228,7 @@ def setup_fetch_data(
):
tool = cached_create_tool_from_representation(app=app, raw_tool_source=raw_tool_source)
job = sa_session.get(Job, job_id)
assert job
# self.request.hostname is the actual worker name given by the `-n` argument, not the hostname as you might think.
job.handler = self.request.hostname
job.job_runner_name = "celery"
Expand Down Expand Up @@ -260,6 +261,7 @@ def finish_job(
):
tool = cached_create_tool_from_representation(app=app, raw_tool_source=raw_tool_source)
job = sa_session.get(Job, job_id)
assert job
# TODO: assert state ?
mini_job_wrapper = MinimalJobWrapper(job=job, app=app, tool=tool)
mini_job_wrapper.finish("", "")
Expand Down Expand Up @@ -320,6 +322,7 @@ def fetch_data(
task_user_id: Optional[int] = None,
) -> str:
job = sa_session.get(Job, job_id)
assert job
mini_job_wrapper = MinimalJobWrapper(job=job, app=app)
mini_job_wrapper.change_state(model.Job.states.RUNNING, flush=True, job=job)
return abort_when_job_stops(_fetch_data, session=sa_session, job_id=job_id, setup_return=setup_return)
Expand Down
31 changes: 0 additions & 31 deletions lib/galaxy/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,6 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._override_tempdir(kwargs)
self._configure_sqlalchemy20_warnings(kwargs)
self._process_config(kwargs)
self._set_dependent_defaults()

Expand All @@ -764,36 +763,6 @@ def _set_dependent_defaults(self):
f"{dependent_config_param}, {config_param}"
)

def _configure_sqlalchemy20_warnings(self, kwargs):
"""
This method should be deleted after migration to SQLAlchemy 2.0 is complete.
To enable warnings, set `GALAXY_CONFIG_SQLALCHEMY_WARN_20=1`,
"""
warn = string_as_bool(kwargs.get("sqlalchemy_warn_20", False))
if warn:
import sqlalchemy

sqlalchemy.util.deprecations.SQLALCHEMY_WARN_20 = True
self._setup_sqlalchemy20_warnings_filters()

def _setup_sqlalchemy20_warnings_filters(self):
import warnings

from sqlalchemy.exc import RemovedIn20Warning

# Always display RemovedIn20Warning warnings.
warnings.filterwarnings("always", category=RemovedIn20Warning)
# Optionally, enable filters for specific warnings (raise error, or log, etc.)
# messages = [
# r"replace with warning text to match",
# ]
# for msg in messages:
# warnings.filterwarnings('error', message=msg, category=RemovedIn20Warning)
#
# See documentation:
# https://docs.python.org/3.7/library/warnings.html#the-warnings-filter
# https://docs.sqlalchemy.org/en/14/changelog/migration_20.html#migration-to-2-0-step-three-resolve-all-removedin20warnings

def _load_schema(self):
return AppSchema(GALAXY_CONFIG_SCHEMA_PATH, GALAXY_APP_NAME)

Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/dependencies/pinned-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ sniffio==1.3.1 ; python_version >= "3.8" and python_version < "3.13"
social-auth-core==4.5.3 ; python_version >= "3.8" and python_version < "3.13"
sortedcontainers==2.4.0 ; python_version >= "3.8" and python_version < "3.13"
spython==0.3.13 ; python_version >= "3.8" and python_version < "3.13"
sqlalchemy==1.4.52 ; python_version >= "3.8" and python_version < "3.13"
sqlalchemy==2.0.25 ; python_version >= "3.8" and python_version < "3.13"
sqlitedict==2.1.0 ; python_version >= "3.8" and python_version < "3.13"
sqlparse==0.4.4 ; python_version >= "3.8" and python_version < "3.13"
starlette-context==0.3.6 ; python_version >= "3.8" and python_version < "3.13"
Expand Down
6 changes: 4 additions & 2 deletions lib/galaxy/jobs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,9 @@ def galaxy_url(self):
return self.get_destination_configuration("galaxy_infrastructure_url")

def get_job(self) -> model.Job:
return self.sa_session.get(Job, self.job_id)
job = self.sa_session.get(Job, self.job_id)
assert job
return job

def get_id_tag(self):
# For compatibility with drmaa, which uses job_id right now, and TaskWrapper
Expand Down Expand Up @@ -1552,7 +1554,7 @@ def change_state(self, state, info=False, flush=True, job=None):
def get_state(self) -> str:
job = self.get_job()
self.sa_session.refresh(job)
return job.state
return job.state # type:ignore[return-value]

def set_runner(self, runner_url, external_id):
log.warning("set_runner() is deprecated, use set_job_destination()")
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/managers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,9 +318,9 @@ def _one_with_recast_errors(self, query: Query) -> U:
# overridden to raise serializable errors
try:
return query.one()
except sqlalchemy.orm.exc.NoResultFound:
except sqlalchemy.exc.NoResultFound:
raise exceptions.ObjectNotFound(f"{self.model_class.__name__} not found")
except sqlalchemy.orm.exc.MultipleResultsFound:
except sqlalchemy.exc.MultipleResultsFound:
raise exceptions.InconsistentDatabase(f"found more than one {self.model_class.__name__}")

# NOTE: at this layer, all ids are expected to be decoded and in int form
Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/managers/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ def get_collection_contents(self, trans: ProvidesAppContext, parent_id, limit=No
def _get_collection_contents_qry(self, parent_id, limit=None, offset=None):
"""Build query to find first level of collection contents by containing collection parent_id"""
DCE = model.DatasetCollectionElement
qry = Query(DCE).filter(DCE.dataset_collection_id == parent_id)
qry = Query(DCE).filter(DCE.dataset_collection_id == parent_id) # type:ignore[var-annotated]
qry = qry.order_by(DCE.element_index)
qry = qry.options(
joinedload(model.DatasetCollectionElement.child_collection), joinedload(model.DatasetCollectionElement.hda)
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/managers/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ def purge_datasets(self, request: PurgeDatasetsTaskRequest):
self.error_unless_dataset_purge_allowed()
with self.session().begin():
for dataset_id in request.dataset_ids:
dataset: Dataset = self.session().get(Dataset, dataset_id)
if dataset.user_can_purge:
dataset: Optional[Dataset] = self.session().get(Dataset, dataset_id)
if dataset and dataset.user_can_purge:
try:
dataset.full_delete()
except Exception:
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/managers/dbkeys.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
)

from sqlalchemy import select
from sqlalchemy.orm import Session

from galaxy.model import HistoryDatasetAssociation
from galaxy.model.scoped_session import galaxy_scoped_session
from galaxy.util import (
galaxy_directory,
sanitize_lists_to_string,
Expand Down Expand Up @@ -166,6 +166,6 @@ def get_chrom_info(self, dbkey, trans=None, custom_build_hack_get_len_from_fasta
return (chrom_info, db_dataset)


def get_len_files_by_history(session: Session, history_id: int):
def get_len_files_by_history(session: galaxy_scoped_session, history_id: int):
stmt = select(HistoryDatasetAssociation).filter_by(history_id=history_id, extension="len", deleted=False)
return session.scalars(stmt)
6 changes: 3 additions & 3 deletions lib/galaxy/managers/export_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
and_,
select,
)
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm.scoping import scoped_session

from galaxy.exceptions import ObjectNotFound
Expand Down Expand Up @@ -44,7 +44,7 @@ def set_export_association_metadata(self, export_association_id: int, export_met
export_association: StoreExportAssociation = self.session.execute(stmt).scalars().one()
except NoResultFound:
raise ObjectNotFound("Cannot set export metadata. Reason: Export association not found")
export_association.export_metadata = export_metadata.json()
export_association.export_metadata = export_metadata.model_dump_json() # type:ignore[assignment]
with transaction(self.session):
jdavcs marked this conversation as resolved.
Show resolved Hide resolved
self.session.commit()

Expand Down Expand Up @@ -76,4 +76,4 @@ def get_object_exports(
stmt = stmt.offset(offset)
if limit:
stmt = stmt.limit(limit)
return self.session.execute(stmt).scalars()
return self.session.execute(stmt).scalars() # type:ignore[return-value]
9 changes: 5 additions & 4 deletions lib/galaxy/managers/folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
or_,
select,
)
from sqlalchemy.orm import aliased
from sqlalchemy.orm.exc import (
from sqlalchemy.exc import (
MultipleResultsFound,
NoResultFound,
)
from sqlalchemy.orm import aliased

from galaxy import (
model,
Expand Down Expand Up @@ -505,7 +505,7 @@ def _get_contained_datasets_statement(
stmt = stmt.where(
or_(
func.lower(ldda.name).contains(search_text, autoescape=True),
func.lower(ldda.message).contains(search_text, autoescape=True),
func.lower(ldda.message).contains(search_text, autoescape=True), # type:ignore[attr-defined]
)
)
sort_column = LDDA_SORT_COLUMN_MAP[payload.order_by](ldda, associated_dataset)
Expand Down Expand Up @@ -536,7 +536,7 @@ def _filter_by_include_deleted(

def build_folder_path(
self, sa_session: galaxy_scoped_session, folder: model.LibraryFolder
) -> List[Tuple[str, str]]:
) -> List[Tuple[int, Optional[str]]]:
"""
Returns the folder path from root to the given folder.

Expand All @@ -546,6 +546,7 @@ def build_folder_path(
path_to_root = [(current_folder.id, current_folder.name)]
while current_folder.parent_id is not None:
parent_folder = sa_session.get(LibraryFolder, current_folder.parent_id)
assert parent_folder
current_folder = parent_folder
path_to_root.insert(0, (current_folder.id, current_folder.name))
return path_to_root
Expand Down
9 changes: 6 additions & 3 deletions lib/galaxy/managers/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from sqlalchemy import select
from sqlalchemy.orm import exc as sqlalchemy_exceptions
from sqlalchemy.exc import (
MultipleResultsFound,
NoResultFound,
)

from galaxy.exceptions import (
InconsistentDatabase,
Expand Down Expand Up @@ -59,9 +62,9 @@ def get(self, trans: ProvidesUserContext, form_id: int) -> FormDefinitionCurrent
try:
stmt = select(FormDefinitionCurrent).where(FormDefinitionCurrent.id == form_id)
form = self.session().execute(stmt).scalar_one()
except sqlalchemy_exceptions.MultipleResultsFound:
except MultipleResultsFound:
raise InconsistentDatabase("Multiple forms found with the same id.")
except sqlalchemy_exceptions.NoResultFound:
except NoResultFound:
raise RequestParameterInvalidException("No accessible form found with the id provided.")
except Exception as e:
raise InternalServerError(f"Error loading from the database.{unicodify(e)}")
Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/managers/genomes.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def _create_genome_filter(model_class=None):
if self.database_connection.startswith("postgres"):
column = text("convert_from(metadata, 'UTF8')::json ->> 'dbkey'")
else:
column = func.json_extract(model_class.table.c._metadata, "$.dbkey")
column = func.json_extract(model_class.table.c._metadata, "$.dbkey") # type:ignore[assignment]
lower_val = val.lower() # Ignore case
# dbkey can either be "hg38" or '["hg38"]', so we need to check both
if op == "eq":
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/managers/group_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
)

from sqlalchemy import select
from sqlalchemy.orm import Session

from galaxy import model
from galaxy.exceptions import ObjectNotFound
from galaxy.managers.context import ProvidesAppContext
from galaxy.model import GroupRoleAssociation
from galaxy.model.base import transaction
from galaxy.model.scoped_session import galaxy_scoped_session
from galaxy.structured_app import MinimalManagerApp

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -93,7 +93,7 @@ def _remove_role_from_group(self, trans: ProvidesAppContext, group_role: model.G
trans.sa_session.commit()


def get_group_role(session: Session, group, role) -> Optional[GroupRoleAssociation]:
def get_group_role(session: galaxy_scoped_session, group, role) -> Optional[GroupRoleAssociation]:
stmt = (
select(GroupRoleAssociation).where(GroupRoleAssociation.group == group).where(GroupRoleAssociation.role == role)
)
Expand Down
4 changes: 2 additions & 2 deletions lib/galaxy/managers/group_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
)

from sqlalchemy import select
from sqlalchemy.orm import Session

from galaxy import model
from galaxy.exceptions import ObjectNotFound
Expand All @@ -15,6 +14,7 @@
UserGroupAssociation,
)
from galaxy.model.base import transaction
from galaxy.model.scoped_session import galaxy_scoped_session
from galaxy.structured_app import MinimalManagerApp

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -96,7 +96,7 @@ def _remove_user_from_group(self, trans: ProvidesAppContext, group_user: model.U
trans.sa_session.commit()


def get_group_user(session: Session, user, group) -> Optional[UserGroupAssociation]:
def get_group_user(session: galaxy_scoped_session, user, group) -> Optional[UserGroupAssociation]:
stmt = (
select(UserGroupAssociation).where(UserGroupAssociation.user == user).where(UserGroupAssociation.group == group)
)
Expand Down
Loading
Loading