1

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

  1. Is it possible to get a psycopg2 connection object from pytest-pgsql?
  2. Is there a different test fixture I should consider instead? (Not keen on pytest-postgresql because of the restriction to psycopg version 3.)
  3. Is it a design error to pass a connection object from a specific driver to my DataStore wrapper class?
Harry Braviner
  • 627
  • 4
  • 12

0 Answers0