--- obspy/clients/filesystem/db.py +++ obspy/clients/filesystem/db.py @@ -11,22 +11,9 @@ import datetime from sqlalchemy import Column, String, Integer, Float -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import declarative_base from sqlalchemy.schema import PrimaryKeyConstraint - -# we pinned our dependency to sqlalchemy <2.0 for now, so these warnings are -# irrelevant. eventually code should be migrated to work with sqlalchemy >=2.0 -# as well -try: - from sqlalchemy.exc import MovedIn20Warning -except ImportError: - pass -else: - import warnings - warnings.filterwarnings('ignore', category=MovedIn20Warning) - - Base = declarative_base() # Every declarative class should only be instantiated once. Thus we just use a --- obspy/clients/filesystem/tsindex.py +++ obspy/clients/filesystem/tsindex.py @@ -1544,18 +1544,22 @@ def _fetch_index_rows(self, query_rows=None, bulk_params=None): # Create a CTE that contains the request try: stmts = [ - sa.select([ + sa.select( sa.literal(a).label("network"), sa.literal(b).label("station"), sa.literal(c).label("location"), sa.literal(d).label("channel"), - sa.literal(e).label("starttime") - if e != '*' else - sa.literal('0000-00-00T00:00:00').label("starttime"), - sa.literal(f).label("endtime") - if f != '*' else - sa.literal('5000-00-00T00:00:00').label("endtime") - ]) + sa.case( + (sa.literal(e) == '*', + sa.literal('0000-00-00T00:00:00')), + (sa.literal(e) != '*', sa.literal(e)) + ).label("starttime"), + sa.case( + (sa.literal(f) == '*', + sa.literal('5000-00-00T00:00:00')), + (sa.literal(f) != '*', sa.literal(f)) + ).label("endtime") + ) for idx, (a, b, c, d, e, f) in enumerate(query_rows) ] requests = sa.union_all(*stmts) @@ -1724,18 +1728,22 @@ def _fetch_summary_rows(self, query_rows): try: request_cte_name = "request_cte" stmts = [ - sa.select([ + sa.select( sa.literal(a).label("network"), sa.literal(b).label("station"), sa.literal(c).label("location"), sa.literal(d).label("channel"), - sa.literal(e).label("starttime") - if e != '*' else - sa.literal('0000-00-00T00:00:00').label("starttime"), - sa.literal(f).label("endtime") - if f != '*' else - sa.literal('5000-00-00T00:00:00').label("endtime") - ]) + sa.case( + (sa.literal(e) == '*', + sa.literal('0000-00-00T00:00:00')), + (sa.literal(e) != '*', sa.literal(e)) + ).label("starttime"), + sa.case( + (sa.literal(f) == '*', + sa.literal('5000-00-00T00:00:00')), + (sa.literal(f) != '*', sa.literal(f)) + ).label("endtime") + ) for idx, (a, b, c, d, e, f) in enumerate(query_rows) ] requests = sa.union_all(*stmts) --- obspy/pytest.ini +++ obspy/pytest.ini @@ -22,14 +22,6 @@ filterwarnings = ignore:Auto-removal of grids # see issue 3164, can be removed when NRL online tests get removed ignore:(?s).*Direct access to online NRL -# sqlalchemy showing deprecation warnings, seems like big API change with version 2 -# fixed sqlalchemy<2 for now in setup.py -# also suppressing these warnings directly in clients.filesystem.db because -# they get raised before test execution during test discovery -# see https://docs.sqlalchemy.org/en/20/errors.html#error-b8d9 -# see https://docs.sqlalchemy.org/en/20/changelog/migration_20.html - ignore:Deprecated API features .* are not compatible with SQLAlchemy 2.0 - ignore:function is now available as sqlalchemy.orm.declarative_base # ignore DeprecationWarnings and PendingDeprecationWarnings triggered by other modules ignore::DeprecationWarning:(?!obspy).* ignore::PendingDeprecationWarning:(?!obspy).* --- setup.py +++ setup.py @@ -92,7 +92,7 @@ 'matplotlib>=3.3', 'lxml', 'setuptools', - 'sqlalchemy<2', + 'sqlalchemy>=1.4', 'decorator', 'requests', ]