Why I am trying to do this
I want to abstract some operations on a database behind a python class called DataStore
. This will have methods such as get_last_update_for_user(username: str) -> date
that abstract away the need for anyone using the database to understand any SQL.
I would like the constructor of DataStore
to take a psycopg2 connection
object as an argument, and use that to connect to the relevant database. Responsibility for creating the connection
object will lie with the calling code.
My understanding is that psycopg2 is a performant Postgres database driver for python and a reasonable option for this.
Testing
I want to have unit tests for methods such as get_last_update_for_user
, to ensure that my queries are behaving as I expect (particularly for more complex queries). To do so I need to set up a database as a test fixture.
I am trying to do this using pytest-pgsql. My understanding is that this uses psycopg2 as its driver. However, I am not able to work out how to get a psycopg2 connection
object. I am only able to get SQLAlchemy objects. e.g. the following
import pytest_pgsql
def test_foo(postgresql_db: pytest_pgsql.PostgreSQLTestDB):
with postgresql_db.engine.connect() as conn:
print(conn)
conn.cursor()
will print <sqlalchemy.engine.base.Connection object at 0x7f983aa503a0>
and raise an exception: AttributeError: 'Connection' object has no attribute 'cursor'
Questions
- Is it possible to get a psycopg2
connection
object frompytest-pgsql
? - Is there a different test fixture I should consider instead? (Not keen on
pytest-postgresql
because of the restriction to psycopg version 3.) - Is it a design error to pass a connection object from a specific driver to my
DataStore
wrapper class?