diff --git a/README.rst b/README.rst index 7a69ccdf..185ac6d1 100644 --- a/README.rst +++ b/README.rst @@ -105,6 +105,31 @@ If you want the database fixture to be automatically populated with your schema: The database will still be dropped each time. +If you've got other programmatic ways to populate the database, you would need an additional fixture, that will take care of that: + +.. code-block:: python + + @pytest.fixture(scope='function') + def db_session(postgresql): + """Session for SQLAlchemy.""" + from pyramid_fullauth.models import Base # pylint:disable=import-outside-toplevel + + # NOTE: this fstring assumes that psycopg2 >= 2.8 is used. Not sure about it's support in psycopg2cffi (PyPy) + connection = f'postgresql+psycopg2://{postgres.info.user}:@{postgres.info.host}:{postgres.info.port}/{postgres.info.dbname}' + + engine = create_engine(connection, echo=False, poolclass=NullPool) + pyramid_basemodel.Session = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) + pyramid_basemodel.bind_engine( + engine, pyramid_basemodel.Session, should_create=True, should_drop=True) + + yield pyramid_basemodel.Session + + transaction.commit() + Base.metadata.drop_all(engine) + +See the original code at `pyramid_fullauth `_. +Depending on your needs, that in between code can fire alembic migrations in case of sqlalchemy stack or any other code + Connecting to already existing postgresql database diff --git a/src/pytest_postgresql/compat.py b/src/pytest_postgresql/compat.py new file mode 100644 index 00000000..e5e6c82d --- /dev/null +++ b/src/pytest_postgresql/compat.py @@ -0,0 +1,19 @@ +from typing import Any +from platform import python_implementation + +try: + import psycopg2 +except ImportError: + psycopg2 = False + +if not psycopg2: + # if there's no postgres, just go with the flow. + # pylint:disable=invalid-name + cursor = Any + connection = Any +elif python_implementation() == "PyPy": + from psycopg2cffi._impl.cursor import Cursor as cursor + from psycopg2cffi._impl.connection import Connection as connection +else: + from psycopg2._psycopg import cursor + from psycopg2._psycopg import connection \ No newline at end of file diff --git a/src/pytest_postgresql/factories.py b/src/pytest_postgresql/factories.py index 91935c05..3b498225 100644 --- a/src/pytest_postgresql/factories.py +++ b/src/pytest_postgresql/factories.py @@ -25,8 +25,9 @@ import pytest +from pytest_postgresql.compat import psycopg2, connection from pytest_postgresql.executor_noop import NoopExecutor -from pytest_postgresql.janitor import DatabaseJanitor, psycopg2 +from pytest_postgresql.janitor import DatabaseJanitor from pytest_postgresql.executor import PostgreSQLExecutor from pytest_postgresql.port import get_port @@ -242,7 +243,7 @@ def postgresql_factory(request): pg_user, pg_host, pg_port, pg_db, proc_fixture.version, pg_password ): - connection = psycopg2.connect( + db_connection: connection = psycopg2.connect( dbname=pg_db, user=pg_user, password=pg_password, @@ -253,10 +254,11 @@ def postgresql_factory(request): if pg_load: for filename in pg_load: with open(filename, 'r') as _fd: - with connection.cursor() as cur: + with db_connection.cursor() as cur: cur.execute(_fd.read()) - yield connection - connection.close() + yield db_connection + db_connection.close() + db_connection.info return postgresql_factory diff --git a/src/pytest_postgresql/janitor.py b/src/pytest_postgresql/janitor.py index 98522a39..5ec63819 100644 --- a/src/pytest_postgresql/janitor.py +++ b/src/pytest_postgresql/janitor.py @@ -1,21 +1,14 @@ """Database Janitor.""" from contextlib import contextmanager from types import TracebackType -from typing import TypeVar, Union, Optional, Type, Any +from typing import TypeVar, Union, Optional, Type from pkg_resources import parse_version + +from pytest_postgresql.compat import psycopg2, cursor + Version = type(parse_version('1')) # pylint:disable=invalid-name -try: - import psycopg2 - try: - from psycopg2._psycopg import cursor - except ImportError: - from psycopg2cffi._impl.cursor import Cursor as cursor -except ImportError: - psycopg2 = False - # if there's no postgres, just go with the flow. - cursor = Any # pylint:disable=invalid-name DatabaseJanitorType = TypeVar("DatabaseJanitorType", bound="DatabaseJanitor")