Merge pull request #4319 from minrk/require-sqla-14

require sqlalchemy 1.4
This commit is contained in:
Min RK
2023-02-08 15:31:14 +01:00
committed by GitHub
5 changed files with 19 additions and 43 deletions

View File

@@ -8,9 +8,7 @@ from datetime import datetime, timedelta
import alembic.command
import alembic.config
import sqlalchemy
from alembic.script import ScriptDirectory
from packaging.version import parse as parse_version
from sqlalchemy import (
Boolean,
Column,
@@ -31,18 +29,12 @@ from sqlalchemy import (
from sqlalchemy.orm import (
Session,
backref,
declarative_base,
interfaces,
object_session,
relationship,
sessionmaker,
)
try:
from sqlalchemy.orm import declarative_base
except ImportError:
# sqlalchemy < 1.4
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.pool import StaticPool
from sqlalchemy.types import LargeBinary, Text, TypeDecorator
from tornado.log import app_log
@@ -912,27 +904,19 @@ def register_ping_connection(engine):
@event.listens_for(engine, "engine_connect")
def ping_connection(connection, branch=None):
if branch:
# "branch" refers to a sub-connection of a connection,
# we don't want to bother pinging on these.
return
# TODO: remove unused branch arg when we require sqlalchemy 2.0
# turn off "close with result". This flag is only used with
# "connectionless" execution, otherwise will be False in any case
save_should_close_with_result = connection.should_close_with_result
connection.should_close_with_result = False
if parse_version(sqlalchemy.__version__) < parse_version("1.4"):
one = [1]
else:
one = 1
try:
# run a SELECT 1. use a core select() so that
# the SELECT of a scalar value without a table is
# appropriately formatted for the backend
with connection.begin() as transaction:
connection.scalar(select(one))
connection.scalar(select(1))
except exc.DBAPIError as err:
# catch SQLAlchemy's DBAPIError, which is a wrapper
# for the DBAPI's exception. It includes a .connection_invalidated
@@ -948,7 +932,7 @@ def register_ping_connection(engine):
# here also causes the whole connection pool to be invalidated
# so that all stale connections are discarded.
with connection.begin() as transaction:
connection.scalar(select(one))
connection.scalar(select(1))
else:
raise
finally:
@@ -972,11 +956,8 @@ def check_db_revision(engine):
from .dbutil import _temp_alembic_ini
if hasattr(engine.url, "render_as_string"):
# sqlalchemy >= 1.4
# alembic needs the password if it's in the URL
engine_url = engine.url.render_as_string(hide_password=False)
else:
engine_url = str(engine.url)
with _temp_alembic_ini(engine_url) as ini:
cfg = alembic.config.Config(ini)
@@ -1067,6 +1048,8 @@ def new_session_factory(
elif url.startswith('mysql'):
kwargs.setdefault('pool_recycle', 60)
kwargs.setdefault("future", True)
if url.endswith(':memory:'):
# If we're using an in-memory database, ensure that only one connection
# is ever created.

View File

@@ -5,6 +5,7 @@ from glob import glob
from subprocess import check_call
import pytest
from packaging.version import parse as V
from pytest import raises
from traitlets.config import Config
@@ -25,8 +26,14 @@ def generate_old_db(env_dir, hub_version, db_url):
env_pip = os.path.join(env_dir, 'bin', 'pip')
env_py = os.path.join(env_dir, 'bin', 'python')
check_call([sys.executable, '-m', 'virtualenv', env_dir])
pkgs = ['jupyterhub==' + hub_version]
# older jupyterhub needs older sqlachemy version
pkgs = ['jupyterhub==' + hub_version, 'sqlalchemy<1.4']
if V(hub_version) < V("2"):
pkgs.append('sqlalchemy<1.4')
elif V(hub_version) < V("3.1.1"):
pkgs.append('sqlalchemy<2')
if 'mysql' in db_url:
pkgs.append('mysql-connector-python')
elif 'postgres' in db_url:

View File

@@ -14,20 +14,6 @@ from jupyterhub.objects import Server
from jupyterhub.roles import assign_default_roles, update_roles
from jupyterhub.utils import url_path_join as ujoin
try:
from sqlalchemy.exc import RemovedIn20Warning
except ImportError:
class RemovedIn20Warning(DeprecationWarning):
"""
I only exist so I can be used in warnings filters in pytest.ini
I will never be displayed.
sqlalchemy 1.4 introduces RemovedIn20Warning,
but we still test against older sqlalchemy.
"""
class _AsyncRequests:
"""Wrapper around requests to return a Future from request methods

View File

@@ -20,5 +20,5 @@ markers =
selenium: web tests that run with selenium
filterwarnings =
error:.*:jupyterhub.tests.utils.RemovedIn20Warning
ignore:.*event listener has changed as of version 2.0.*:sqlalchemy.exc.SADeprecationWarning
ignore:.*The new signature is "def engine_connect\(conn\)"*:sqlalchemy.exc.SADeprecationWarning
ignore:.*The new signature is "def engine_connect\(conn\)"*:sqlalchemy.exc.SAWarning

View File

@@ -11,6 +11,6 @@ prometheus_client>=0.4.0
psutil>=5.6.5; sys_platform == 'win32'
python-dateutil
requests
SQLAlchemy>=1.1
SQLAlchemy>=1.4
tornado>=5.1
traitlets>=4.3.2