mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-13 04:53:01 +00:00
Merge pull request #4319 from minrk/require-sqla-14
require sqlalchemy 1.4
This commit is contained in:
@@ -8,9 +8,7 @@ from datetime import datetime, timedelta
|
|||||||
|
|
||||||
import alembic.command
|
import alembic.command
|
||||||
import alembic.config
|
import alembic.config
|
||||||
import sqlalchemy
|
|
||||||
from alembic.script import ScriptDirectory
|
from alembic.script import ScriptDirectory
|
||||||
from packaging.version import parse as parse_version
|
|
||||||
from sqlalchemy import (
|
from sqlalchemy import (
|
||||||
Boolean,
|
Boolean,
|
||||||
Column,
|
Column,
|
||||||
@@ -31,18 +29,12 @@ from sqlalchemy import (
|
|||||||
from sqlalchemy.orm import (
|
from sqlalchemy.orm import (
|
||||||
Session,
|
Session,
|
||||||
backref,
|
backref,
|
||||||
|
declarative_base,
|
||||||
interfaces,
|
interfaces,
|
||||||
object_session,
|
object_session,
|
||||||
relationship,
|
relationship,
|
||||||
sessionmaker,
|
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.pool import StaticPool
|
||||||
from sqlalchemy.types import LargeBinary, Text, TypeDecorator
|
from sqlalchemy.types import LargeBinary, Text, TypeDecorator
|
||||||
from tornado.log import app_log
|
from tornado.log import app_log
|
||||||
@@ -912,27 +904,19 @@ def register_ping_connection(engine):
|
|||||||
|
|
||||||
@event.listens_for(engine, "engine_connect")
|
@event.listens_for(engine, "engine_connect")
|
||||||
def ping_connection(connection, branch=None):
|
def ping_connection(connection, branch=None):
|
||||||
if branch:
|
# TODO: remove unused branch arg when we require sqlalchemy 2.0
|
||||||
# "branch" refers to a sub-connection of a connection,
|
|
||||||
# we don't want to bother pinging on these.
|
|
||||||
return
|
|
||||||
|
|
||||||
# turn off "close with result". This flag is only used with
|
# turn off "close with result". This flag is only used with
|
||||||
# "connectionless" execution, otherwise will be False in any case
|
# "connectionless" execution, otherwise will be False in any case
|
||||||
save_should_close_with_result = connection.should_close_with_result
|
save_should_close_with_result = connection.should_close_with_result
|
||||||
connection.should_close_with_result = False
|
connection.should_close_with_result = False
|
||||||
|
|
||||||
if parse_version(sqlalchemy.__version__) < parse_version("1.4"):
|
|
||||||
one = [1]
|
|
||||||
else:
|
|
||||||
one = 1
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# run a SELECT 1. use a core select() so that
|
# run a SELECT 1. use a core select() so that
|
||||||
# the SELECT of a scalar value without a table is
|
# the SELECT of a scalar value without a table is
|
||||||
# appropriately formatted for the backend
|
# appropriately formatted for the backend
|
||||||
with connection.begin() as transaction:
|
with connection.begin() as transaction:
|
||||||
connection.scalar(select(one))
|
connection.scalar(select(1))
|
||||||
except exc.DBAPIError as err:
|
except exc.DBAPIError as err:
|
||||||
# catch SQLAlchemy's DBAPIError, which is a wrapper
|
# catch SQLAlchemy's DBAPIError, which is a wrapper
|
||||||
# for the DBAPI's exception. It includes a .connection_invalidated
|
# 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
|
# here also causes the whole connection pool to be invalidated
|
||||||
# so that all stale connections are discarded.
|
# so that all stale connections are discarded.
|
||||||
with connection.begin() as transaction:
|
with connection.begin() as transaction:
|
||||||
connection.scalar(select(one))
|
connection.scalar(select(1))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
@@ -972,11 +956,8 @@ def check_db_revision(engine):
|
|||||||
|
|
||||||
from .dbutil import _temp_alembic_ini
|
from .dbutil import _temp_alembic_ini
|
||||||
|
|
||||||
if hasattr(engine.url, "render_as_string"):
|
# alembic needs the password if it's in the URL
|
||||||
# sqlalchemy >= 1.4
|
|
||||||
engine_url = engine.url.render_as_string(hide_password=False)
|
engine_url = engine.url.render_as_string(hide_password=False)
|
||||||
else:
|
|
||||||
engine_url = str(engine.url)
|
|
||||||
|
|
||||||
with _temp_alembic_ini(engine_url) as ini:
|
with _temp_alembic_ini(engine_url) as ini:
|
||||||
cfg = alembic.config.Config(ini)
|
cfg = alembic.config.Config(ini)
|
||||||
@@ -1067,6 +1048,8 @@ def new_session_factory(
|
|||||||
elif url.startswith('mysql'):
|
elif url.startswith('mysql'):
|
||||||
kwargs.setdefault('pool_recycle', 60)
|
kwargs.setdefault('pool_recycle', 60)
|
||||||
|
|
||||||
|
kwargs.setdefault("future", True)
|
||||||
|
|
||||||
if url.endswith(':memory:'):
|
if url.endswith(':memory:'):
|
||||||
# If we're using an in-memory database, ensure that only one connection
|
# If we're using an in-memory database, ensure that only one connection
|
||||||
# is ever created.
|
# is ever created.
|
||||||
|
@@ -5,6 +5,7 @@ from glob import glob
|
|||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from packaging.version import parse as V
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
from traitlets.config import Config
|
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_pip = os.path.join(env_dir, 'bin', 'pip')
|
||||||
env_py = os.path.join(env_dir, 'bin', 'python')
|
env_py = os.path.join(env_dir, 'bin', 'python')
|
||||||
check_call([sys.executable, '-m', 'virtualenv', env_dir])
|
check_call([sys.executable, '-m', 'virtualenv', env_dir])
|
||||||
|
pkgs = ['jupyterhub==' + hub_version]
|
||||||
|
|
||||||
# older jupyterhub needs older sqlachemy 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:
|
if 'mysql' in db_url:
|
||||||
pkgs.append('mysql-connector-python')
|
pkgs.append('mysql-connector-python')
|
||||||
elif 'postgres' in db_url:
|
elif 'postgres' in db_url:
|
||||||
|
@@ -14,20 +14,6 @@ from jupyterhub.objects import Server
|
|||||||
from jupyterhub.roles import assign_default_roles, update_roles
|
from jupyterhub.roles import assign_default_roles, update_roles
|
||||||
from jupyterhub.utils import url_path_join as ujoin
|
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:
|
class _AsyncRequests:
|
||||||
"""Wrapper around requests to return a Future from request methods
|
"""Wrapper around requests to return a Future from request methods
|
||||||
|
@@ -20,5 +20,5 @@ markers =
|
|||||||
selenium: web tests that run with selenium
|
selenium: web tests that run with selenium
|
||||||
|
|
||||||
filterwarnings =
|
filterwarnings =
|
||||||
error:.*:jupyterhub.tests.utils.RemovedIn20Warning
|
ignore:.*The new signature is "def engine_connect\(conn\)"*:sqlalchemy.exc.SADeprecationWarning
|
||||||
ignore:.*event listener has changed as of version 2.0.*:sqlalchemy.exc.SADeprecationWarning
|
ignore:.*The new signature is "def engine_connect\(conn\)"*:sqlalchemy.exc.SAWarning
|
||||||
|
@@ -11,6 +11,6 @@ prometheus_client>=0.4.0
|
|||||||
psutil>=5.6.5; sys_platform == 'win32'
|
psutil>=5.6.5; sys_platform == 'win32'
|
||||||
python-dateutil
|
python-dateutil
|
||||||
requests
|
requests
|
||||||
SQLAlchemy>=1.1
|
SQLAlchemy>=1.4
|
||||||
tornado>=5.1
|
tornado>=5.1
|
||||||
traitlets>=4.3.2
|
traitlets>=4.3.2
|
||||||
|
Reference in New Issue
Block a user