Skip to main content

Python testing library for PGlite - in-memory PostgreSQL for tests

Project description

py-pglite

py-pglite Logo

Instant PostgreSQL for Python testing

pip install py-pglite


def test_users(pglite_session):
    user = User(name="Alice")
    pglite_session.add(user)
    pglite_session.commit()
    assert user.id == 1  # It's real PostgreSQL!

That's it. No Docker, no setup, no config files. Real PostgreSQL, instant testing.

CI PyPI Python

License MyPy Ruff codecov


Why py-pglite?

# ❌ Traditional testing
def test_old_way():
    # 1. Install PostgreSQL
    # 2. Configure connection  
    # 3. Manage test databases
    # 4. Handle cleanup
    # 5. Docker containers...
    pass

# ✅ py-pglite way  
def test_new_way(pglite_session):
    User.objects.create(name="Alice")  # Just works!

The magic:

  • 🎯 Zero config - No setup, no Docker, no servers
  • Instant - 2-3s startup vs 30-60s Docker
  • 🔄 Isolated - Fresh database per test
  • 🐘 Real PostgreSQL - JSON, arrays, window functions
  • 🚀 Any client - SQLAlchemy, Django, psycopg, asyncpg

Install

# Core (framework-agnostic)
pip install py-pglite

# With your stack
pip install py-pglite[sqlalchemy]  # SQLAlchemy + SQLModel
pip install py-pglite[django]      # Django + pytest-django  
pip install py-pglite[asyncpg]     # Pure async client
pip install py-pglite[all]         # Everything

Quick Start

SQLAlchemy (Zero imports needed)

def test_sqlalchemy_just_works(pglite_session):
    user = User(name="Alice", email="alice@test.com")  
    pglite_session.add(user)
    pglite_session.commit()
    
    assert user.id is not None
    assert User.query.count() == 1  # Real PostgreSQL!

Django (Auto-configured)

def test_django_just_works(db):
    Post.objects.create(title="Hello", content="World")
    assert Post.objects.count() == 1  # Real PostgreSQL!

Any PostgreSQL client

def test_any_client_works(pglite_manager):
    # Extract connection details
    engine = pglite_manager.get_engine()
    host, port, database = str(engine.url.host), engine.url.port, engine.url.database
    
    # Use with any PostgreSQL client
    # conn = psycopg.connect(host=host, port=port, dbname=database)
    # conn = await asyncpg.connect(host=host, port=port, database=database)
    # engine = create_async_engine(f"postgresql+asyncpg://{host}:{port}/{database}")

Examples

FastAPI + SQLModel

from fastapi.testclient import TestClient

def test_api_endpoint(client: TestClient):
    response = client.post("/users/", json={"name": "Alice"})
    assert response.status_code == 201
    
    response = client.get("/users/")
    assert len(response.json()) == 1

PostgreSQL Features

def test_postgresql_power(pglite_session):
    pglite_session.execute(text("""
        CREATE TABLE analytics (
            data JSONB,
            tags TEXT[],
            created TIMESTAMP DEFAULT NOW()
        )
    """))
    
    pglite_session.execute(text("""
        INSERT INTO analytics (data, tags) VALUES 
        ('{"clicks": 100}', ARRAY['web', 'mobile'])
    """))
    
    result = pglite_session.execute(text("""
        SELECT data->>'clicks' as clicks,
               array_length(tags, 1) as tag_count
        FROM analytics 
        WHERE data->>'clicks' > '50'
    """)).fetchone()
    
    assert result.clicks == '100'

Advanced

🔧 Production Configuration
from py_pglite import PGliteConfig
from py_pglite.sqlalchemy import SQLAlchemyPGliteManager

config = PGliteConfig(
    timeout=60,                    # Extended timeout for CI/CD
    log_level="INFO",              # Balanced logging
    cleanup_on_exit=True,          # Automatic cleanup
    work_dir=Path("./test-data")   # Custom directory
)

with SQLAlchemyPGliteManager(config) as manager:
    engine = manager.get_engine(
        pool_recycle=3600,         # Connection recycling
        echo=False                 # SQL logging
    )
🔄 Client Compatibility
# py-pglite provides a REAL PostgreSQL server - any client works!

with SQLAlchemyPGliteManager() as manager:
    engine = manager.get_engine()
    url = engine.url
    
    # Extract connection details for any PostgreSQL client
    host, port, database = str(url.host), url.port, url.database
    
    # Examples for different clients:
    # psycopg:  psycopg.connect(host=host, port=port, dbname=database)
    # asyncpg:  await asyncpg.connect(host=host, port=port, database=database)
    # Django:   Uses custom py-pglite backend automatically

Installation Matrix:

Client Install Use Case
[sqlalchemy] SQLAlchemy + SQLModel ORM, modern Python
[django] Django + pytest-django Django projects
[psycopg] psycopg (sync/async) Raw SQL, custom
[asyncpg] Pure async client High-performance async
[all] Everything Full compatibility
🎯 Framework Isolation
# Perfect isolation - no framework bleeding
pytest -m sqlalchemy -p no:django     # Pure SQLAlchemy
pytest -m django -p no:sqlalchemy     # Pure Django  
pytest tests/sqlalchemy/              # Directory isolation

Built for developers who want PostgreSQL testing without the complexity.

🎯 Examples • 📚 Contributing • 🐛 Issues


py-pglite: Because testing should be simple.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_pglite-0.3.0.tar.gz (230.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_pglite-0.3.0-py3-none-any.whl (39.2 kB view details)

Uploaded Python 3

File details

Details for the file py_pglite-0.3.0.tar.gz.

File metadata

  • Download URL: py_pglite-0.3.0.tar.gz
  • Upload date:
  • Size: 230.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for py_pglite-0.3.0.tar.gz
Algorithm Hash digest
SHA256 ce4697d0372c1cc2fc1b6bcf20ceb9121f9a0b6f4d48cd457a252f5be0c0adb0
MD5 50b191caf3897df38aa6628d78f47f94
BLAKE2b-256 9bf95474ca661bbca70ce1b0f077541a33026c40720d8e8967c28188c9a8645b

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_pglite-0.3.0.tar.gz:

Publisher: release.yml on wey-gu/py-pglite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file py_pglite-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: py_pglite-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 39.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for py_pglite-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1bb09af53b62eb2494c849e9d4f5846ab1658de71ac1e3e91a1b6b37139b0a8a
MD5 f4e9b3df77d244781220d7bcf194498a
BLAKE2b-256 6297151d24ce62ca0cefa0b8d6d1eb299dff21e8bb63d4426d939bb1f716a486

See more details on using hashes here.

Provenance

The following attestation bundles were made for py_pglite-0.3.0-py3-none-any.whl:

Publisher: release.yml on wey-gu/py-pglite

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page