Skip to content

Commit 40e4d3f

Browse files
committed
drafted repo for asyncio
1 parent 3d6e402 commit 40e4d3f

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

packages/postgres-database/tests/conftest.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import uuid
77
from collections.abc import AsyncIterator, Awaitable, Callable, Iterator
8+
from pathlib import Path
89

910
import aiopg.sa
1011
import aiopg.sa.exc
@@ -36,6 +37,7 @@
3637
user_to_groups,
3738
users,
3839
)
40+
from sqlalchemy.ext.asyncio import AsyncEngine, create_async_engine
3941

4042
pytest_plugins = [
4143
"pytest_simcore.pytest_global_environs",
@@ -47,7 +49,7 @@
4749
def postgres_service(docker_services, docker_ip, docker_compose_file) -> str:
4850
"""Deploys postgres and service is responsive"""
4951
# container environment
50-
with open(docker_compose_file) as fh:
52+
with Path.open(docker_compose_file) as fh:
5153
config = yaml.safe_load(fh)
5254
environ = config["services"]["postgres"]["environment"]
5355

@@ -80,6 +82,29 @@ def _make(is_async=True) -> Awaitable[Engine] | sa.engine.base.Engine:
8082
return _make
8183

8284

85+
@pytest.fixture
86+
def make_asyncio_engine(postgres_service: str) -> Callable[[bool], AsyncEngine]:
87+
dsn = postgres_service.replace("postgresql://", "postgresql+asyncpg://")
88+
minsize = 1
89+
maxsize = 50
90+
91+
def _(echo: bool):
92+
engine: AsyncEngine = create_async_engine(
93+
dsn,
94+
pool_size=minsize,
95+
max_overflow=maxsize - minsize,
96+
connect_args={
97+
"server_settings": {"application_name": "postgres_database_tests"}
98+
},
99+
pool_pre_ping=True, # https://docs.sqlalchemy.org/en/14/core/pooling.html#dealing-with-disconnects
100+
future=True, # this uses sqlalchemy 2.0 API, shall be removed when sqlalchemy 2.0 is released
101+
echo=echo,
102+
)
103+
return engine
104+
105+
return _
106+
107+
83108
def is_postgres_responsive(dsn) -> bool:
84109
"""Check if something responds to ``url``"""
85110
try:
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# pylint: disable=redefined-outer-name
2+
# pylint: disable=unused-argument
3+
# pylint: disable=unused-variable
4+
# pylint: disable=too-many-arguments
5+
6+
from collections.abc import AsyncIterator, Callable
7+
8+
import sqlalchemy as sa
9+
from simcore_postgres_database.base_repo import MinimalRepo, transaction_context
10+
from sqlalchemy.ext.asyncio import AsyncEngine
11+
12+
13+
async def asyncio_engine(
14+
make_asyncio_engine: Callable[[bool], AsyncEngine]
15+
) -> AsyncIterator[AsyncEngine]:
16+
engine = make_asyncio_engine(echo=True)
17+
try:
18+
yield engine
19+
except Exception:
20+
# for AsyncEngine created in function scope, close and
21+
# clean-up pooled connections
22+
await engine.dispose()
23+
24+
25+
async def test_it(asyncio_engine: AsyncEngine):
26+
27+
meta = sa.MetaData()
28+
t1 = sa.Table("t1", meta, sa.Column("name", sa.String(50), primary_key=True))
29+
30+
t1_repo = MinimalRepo(engine=asyncio_engine, table=t1)
31+
32+
async with transaction_context(asyncio_engine) as conn:
33+
await conn.run_sync(meta.drop_all)
34+
await conn.run_sync(meta.create_all)
35+
36+
await t1_repo.create(conn, name="some name 1")
37+
await t1_repo.create(conn, name="some name 2")
38+
39+
async with transaction_context(asyncio_engine) as conn:
40+
41+
page = await t1_repo.get_page(limit=50, offset=0, connection=conn)
42+
43+
assert page["total_count"] == 2
44+
45+
# select a Result, which will be delivered with buffered
46+
# results
47+
result = await conn.execute(sa.select(t1).where(t1.c.name == "some name 1"))
48+
print(result.fetchall())

0 commit comments

Comments
 (0)