Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 52 additions & 0 deletions tests/test_orm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import pytest

from yhttp.ext.sqlalchemy.orm import ORM


def _engine_url(monkeypatch, url):
seen = {}

def fake_create_engine(target, **kwargs):
seen['url'] = target
seen['kwargs'] = kwargs

class Engine:
def dispose(self):
return None

return Engine()

monkeypatch.setattr(
'yhttp.ext.sqlalchemy.orm.create_engine',
fake_create_engine,
)
orm = ORM(object())
orm.connect(url)
try:
return seen
finally:
orm.disconnect()


@pytest.mark.parametrize('url', (
'postgresql://user:pass@localhost:5432/dbname?sslmode=require',
'postgres://user:pass@localhost:5432/dbname?sslmode=require',
))
def test_driverless_postgresql_uses_psycopg2(monkeypatch, url):
seen = _engine_url(monkeypatch, url)
parsed = seen['url']

assert parsed.drivername == 'postgresql+psycopg2'


@pytest.mark.parametrize('url', (
'postgresql+psycopg2://user:pass@localhost/dbname',
'postgresql+psycopg://user:pass@localhost/dbname',
'postgresql+asyncpg://user:pass@localhost/dbname',
))
def test_explicit_postgresql_driver_unchanged(monkeypatch, url):
seen = _engine_url(monkeypatch, url)

assert seen['url'].drivername == url.split(':', 1)[0]
assert seen['url'].username == 'user'
assert seen['url'].database == 'dbname'
2 changes: 1 addition & 1 deletion yhttp/ext/sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .install import install


__version__ = '6.1.0'
__version__ = '6.1.1'
9 changes: 8 additions & 1 deletion yhttp/ext/sqlalchemy/orm.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlalchemy import create_engine
from sqlalchemy.engine import make_url
from sqlalchemy.orm import sessionmaker, close_all_sessions, Session, \
scoped_session

Expand All @@ -22,8 +23,14 @@ def connect(self, url=None):
assert self.engine is None
assert u is not None

parsed = make_url(u)
if parsed.drivername in ('postgresql', 'postgres'):
# SQLAlchemy 2.1 loads psycopg 3 for a driverless URL.
# https://docs.sqlalchemy.org/en/21/changelog/migration_21.html#default-postgresql-driver-changed-to-psycopg-psycopg-3 # noqa: E501
parsed = parsed.set(drivername='postgresql+psycopg2')

self.engine = create_engine(
u,
parsed,
isolation_level='REPEATABLE READ',
plugins=self.saplugins or [],
)
Expand Down