Skip to main content

Clean PostgreSQL Databases for Your Tests

The following is a summary of the complete pytest_pgsql docs, which are available on ReadTheDocs.

What is pytest_pgsql?

pytest_pgsql is a pytest plugin you can use to write unit tests that utilize a temporary PostgreSQL database that gets cleaned up automatically after every test runs, allowing each test to run on a completely clean database (with some limitations).

The plugin gives you two fixtures you can use in your tests: postgresql_db and transacted_postgresql_db. Both of these give you similar interfaces to access to the database, but have slightly different use cases (see below).

Sample Usage

You can use a session, connection, or engine - the choice is up to you. postgresql_db and transacted_postgresql_db both give you a session, but postgresql_db exposes its engine and transacted_postgresql_db exposes its connection:

def test_orm(postgresql_db):
    instance = Person(name='Foo Bar')
    postgresql_db.session.add(instance)
    postgresql_db.session.commit()
    with postgresql_db.engine.connect() as conn:
        do_thing(conn)

def test_connection(transacted_postgresql_db):
    instance = Person(name='Foo Bar')
    transacted_postgresql_db.session.add(instance)
    transacted_postgresql_db.session.commit()

    transacted_postgresql_db.connection.execute('DROP TABLE my_table')

Features

The following is a non-exhaustive list of some of the features provided to you by the database fixtures.

Manipulating Time

Both database fixtures use freezegun to allow you to freeze time inside a block of code. You can use it in a variety of ways:

As a context manager:

with postgresql.time.freeze('December 31st 1999 11:59:59 PM') as freezer:
    # Time is frozen inside the database *and* Python.
    now = postgresql_db.session.execute('SELECT NOW()').scalar()
    assert now.date() == datetime.date(1999, 12, 31)
    assert datetime.date.today() == datetime.date(1999, 12, 31)

    # Advance time by 1 second so we roll over into the new year
    freezer.tick()

    now = postgresql_db.session.execute('SELECT NOW()').scalar()
    assert now.date() == datetime.date(2000, 1, 1)

As a decorator:

@pytest_pgsql.freeze_time(datetime.datetime(2038, 1, 19, 3, 14, 7))
def test_freezing(postgresql_db):
    today = postgresql_db.session.execute(
        "SELECT EXTRACT('YEAR' FROM CURRENT_DATE)").scalar()
    assert today.year == 2038
    assert datetime.date.today() == datetime.date(2038, 1, 19)

And more!

General-Purpose Functions

postgresql_db and transacted_postgresql_db provide some general-purpose functions to ease test setup and execution.

  • load_csv() loads a CSV file into an existing table.

  • run_sql_file() executes a SQL script, optionally performing variable binding.

Extension Management

Since version 9.1 Postgres supports extensions. You can check for the presence of and install extensions like so:

>>> postgresql_db.is_extension_available('asdf')  # Can I install this extension?
False
>>> postgresql_db.is_extension_available('uuid-ossp')  # Maybe this one is supported...
True
>>> postgresql_db.install_extension('uuid-ossp')
True
>>> postgresql_db.is_extension_installed('uuid-ossp')
True

install_extension() has additional arguments to allow control over which schema the extension is installed in, what to do if the extension is already installed, and so on. See the documentation for descriptions of these features.

Schemas and Tables

You can create table schemas by calling create_schema() like so:

postgresql_db.create_schema('foo')          # Create one schema
postgresql_db.create_schema('foo', 'bar')   # Create multiple ones

To quickly see if a table schema exists, call has_schema():

>>> postgresql_db.has_schema('public')
True

Similarly, you can create tables in the database with create_table(). You can pass SQLAlchemy Table instances or ORM declarative model classes:

# Just a regular Table.
my_table = Table('abc', MetaData(), Column('def', Integer()))

# A declarative model works too.
class MyORMModel(declarative_base()):
    id = Column(Integer, primary_key=True)

# Pass a variable amount of tables to create
postgresql_db.create_table(my_table, MyORMModel)

Installation

Sorry, this library is not compatible with Python 2. Please be sure to use pip3 instead of pip when installing:

pip3 install pytest-pgsql

Contributing Guide

For information on setting up pytest_pgsql for development and contributing changes, view CONTRIBUTING.rst.

Release files for pytest-pgsql 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-pgsql 1.1.2
File Size Uploaded
pytest-pgsql-1.1.2.tar.gz 41.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-pgsql 1.1.2
File Interpreter ABI Platform
pytest_pgsql-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 75.1 kB

Release files / pytest-pgsql-1.1.2.tar.gz

Download URL pytest-pgsql-1.1.2.tar.gz
Size 41.2 kB
Tags Source
SHA-256 checksum
How to use checksums
293462a0b2597598879c64d2c8ca72158a2d236c613d368452b9b00a68f2264f
BLAKE2b-256 checksum
How to use checksums
0c72e3275b23dda9448a1202a11cf0be268e4a4bd30c1abe8c008830906a5887
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.9.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.3.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.6.2

Release files / pytest_pgsql-1.1.2-py3-none-any.whl

Download URL pytest_pgsql-1.1.2-py3-none-any.whl
Size 33.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
45d127ef9f62d29e41803a5695129c086d77666348716d83782abfd77108acfb
BLAKE2b-256 checksum
How to use checksums
b5687b44e25d51a2569ea74626a53072cc9c73388cb495bc3fc0c92157f9c809
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.9.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.3.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.6.2

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page