- Notifications
You must be signed in to change notification settings - Fork18
PGlite wrapper in Python for testing. Test your app with Postgres just as lite as SQLite.
License
wey-gu/py-pglite
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation

A Pythonic interface for PGlite - the instant, zero-config PostgreSQL. ⚡️
py-pglite brings the magic ofPGlite to Python with a high-level, developer-friendly API. Real PostgreSQL, instant testing.
pip install py-pglite
deftest_users(pglite_session):user=User(name="Alice")pglite_session.add(user)pglite_session.commit()assertuser.id==1# It's real PostgreSQL!
That's it. No Docker, no setup, no config files. Real PostgreSQL, instant testing.
# ❌ Traditional testingdeftest_old_way():# 1. Install PostgreSQL# 2. Configure connection# 3. Manage test databases# 4. Handle cleanup# 5. Docker containers...pass# ✅ py-pglite waydeftest_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
# Core (framework-agnostic)pip install py-pglite# With your stackpip install py-pglite[sqlalchemy]# SQLAlchemy + SQLModelpip install py-pglite[django]# Django + pytest-djangopip install py-pglite[asyncpg]# Pure async clientpip install py-pglite[all]# Everything# Extra Featurespip install py-pglite[extensions]# pglite extensions, like pgvector, fuzzystrmatch etc.
deftest_sqlalchemy_just_works(pglite_session):user=User(name="Alice",email="alice@test.com")pglite_session.add(user)pglite_session.commit()assertuser.idisnotNoneassertUser.query.count()==1# Real PostgreSQL!
🔹 Lightweight/Socket (Minimal setup)
deftest_django_socket_pattern(configured_django):Post.objects.create(title="Hello",content="World")assertPost.objects.count()==1# Real PostgreSQL via socket!
🔸 Full Integration/Backend (Enhanced features)
deftest_django_backend_pattern(django_pglite_db):Post.objects.create(title="Hello",content="World",metadata={"tags": ["test"]})assertPost.objects.count()==1# Custom backend with JSON support!
Choose your pattern:
- Lightweight: Fast, minimal dependencies, standard PostgreSQL backend
- Full Integration: Advanced features, custom backend, enhanced JSON support
👉See Django patterns guide for detailed examples and migration guide.
deftest_any_client_works(pglite_manager):# Extract connection detailsengine=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)# engine = create_async_engine(f"postgresql+asyncpg://{host}:{port}/{database}")# For asyncpg specifically, use TCP mode with proper configuration:asyncdeftest_asyncpg_works(pglite_tcp_manager):config=pglite_tcp_manager.configconn=awaitasyncpg.connect(host=config.tcp_host,port=config.tcp_port,user="postgres",password="postgres",database="postgres",ssl=False,server_settings={}# CRITICAL: Required for PGlite compatibility )result=awaitconn.fetchval("SELECT 1")awaitconn.close()
fromfastapi.testclientimportTestClientdeftest_api_endpoint(client:TestClient):response=client.post("/users/",json={"name":"Alice"})assertresponse.status_code==201response=client.get("/users/")assertlen(response.json())==1
deftest_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()assertresult.clicks=='100'
py-pglite supports PostgreSQL extensions, allowing you to test advanced features like vector similarity search for AI/RAG applications.
Enablepgvector to test vector embeddings and similarity search directly in your test suite.
1. Install with the[extensions] extra:
pip install'py-pglite[extensions]'2. Enablepgvector in the configuration:
frompy_pgliteimportPGliteConfig,PGliteManagerfrompgvector.psycopgimportregister_vectorimportpsycopgimportnumpyasnp# Enable the extensionconfig=PGliteConfig(extensions=["pgvector"])withPGliteManager(config=config)asdb:withpsycopg.connect(db.get_dsn(),autocommit=True)asconn:# Create the extension and register the typeconn.execute("CREATE EXTENSION IF NOT EXISTS vector")register_vector(conn)# Create a table and insert a vectorconn.execute("CREATE TABLE items (embedding vector(3))")conn.execute("INSERT INTO items (embedding) VALUES (%s)", (np.array([1,2,3]),))# Perform a similarity searchresult=conn.execute("SELECT * FROM items ORDER BY embedding <-> %s LIMIT 1", (np.array([1,1,1]),)).fetchone()assertnp.array_equal(result[0],np.array([1,2,3]))
py-pglite can support many other extensions available in the underlyingPGlite extensions
🔧 Production Configuration
frompy_pgliteimportPGliteConfigfrompy_pglite.sqlalchemyimportSQLAlchemyPGliteManagerconfig=PGliteConfig(timeout=60,# Extended timeout for CI/CDlog_level="INFO",# Balanced loggingcleanup_on_exit=True,# Automatic cleanupwork_dir=Path("./test-data")# Custom directory)withSQLAlchemyPGliteManager(config)asmanager:engine=manager.get_engine(pool_recycle=3600,# Connection recyclingecho=False# SQL logging )
🌐 Socket Modes (Unix vs TCP)
py-pglite supports both Unix domain sockets (default) and TCP sockets for different use cases:
# Default configuration - uses Unix domain socket for best performancefrompy_pgliteimportPGliteManagerwithPGliteManager()asdb:# Connection via Unix socket - fastest for local testingdsn=db.get_dsn()# host=/tmp/... dbname=postgres
frompy_pgliteimportPGliteConfig,PGliteManager# Enable TCP mode for any TCP-only clientsconfig=PGliteConfig(use_tcp=True,tcp_host="127.0.0.1",# Default: localhost onlytcp_port=5432,# Default: PostgreSQL standard portextensions=["pgvector"])withPGliteManager(config)asdb:# Now compatible with any TCP-only clientsuri=db.get_psycopg_uri()# postgresql://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable
When to use TCP mode:
- Any TCP-only clients (doesn't support Unix sockets)
- Cloud-native testing environments
- Docker containers with network isolation
- Testing network-based database tools
- Required for asyncpg: asyncpg only works in TCP mode
Important notes:
- PGlite Socket supports onlyone active connection at a time
- SSL is not supported - always use
sslmode=disable - Unix sockets are faster for local testing (default)
- TCP mode binds to localhost by default for security
- asyncpg requires
server_settings={}to prevent hanging
🔄 Client Compatibility
# py-pglite provides a REAL PostgreSQL server - any client works!withSQLAlchemyPGliteManager()asmanager:engine=manager.get_engine()url=engine.url# Extract connection details for any PostgreSQL clienthost,port,database=str(url.host),url.port,url.database# Examples for different clients:# psycopg: psycopg.connect(host=host, port=port, dbname=database)# Django: Uses custom py-pglite backend automatically# asyncpg requires TCP mode and specific configuration:config=PGliteConfig(use_tcp=True)withPGliteManager(config)asmanager:conn=awaitasyncpg.connect(host=config.tcp_host,port=config.tcp_port,user="postgres",password="postgres",database="postgres",ssl=False,server_settings={}# Required for PGlite compatibility )
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 bleedingpytest -m sqlalchemy -p no:django# Pure SQLAlchemypytest -m django -p no:sqlalchemy# Pure Djangopytest tests/sqlalchemy/# Directory isolation
Built for developers who want PostgreSQL testing without the complexity.
🎯Examples • 📚Contributing • 🐛Issues
py-pglite: Because testing should be simple. ⚡
Powered by the 🚀 amazing and
About
PGlite wrapper in Python for testing. Test your app with Postgres just as lite as SQLite.
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.