Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

PGlite wrapper in Python for testing. Test your app with Postgres just as lite as SQLite.

License

NotificationsYou must be signed in to change notification settings

wey-gu/py-pglite

Repository files navigation

py-pglite Logo

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.

CIPyPIPython

LicenseMyPyRuffcodecov


Why py-pglite?

# ❌ 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

Install

# 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.

Quick Start

SQLAlchemy (Zero imports needed)

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!

Django

🔹 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.

Any PostgreSQL client

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()

Examples

FastAPI + SQLModel

fromfastapi.testclientimportTestClientdeftest_api_endpoint(client:TestClient):response=client.post("/users/",json={"name":"Alice"})assertresponse.status_code==201response=client.get("/users/")assertlen(response.json())==1

PostgreSQL Features

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'

PostgreSQL Extensions

py-pglite supports PostgreSQL extensions, allowing you to test advanced features like vector similarity search for AI/RAG applications.

🚀pgvector for 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♥️.


Advanced

🔧 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:

Unix Socket Mode (Default)

# 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

TCP Socket Mode

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 usesslmode=disable
  • Unix sockets are faster for local testing (default)
  • TCP mode binds to localhost by default for security
  • asyncpg requiresserver_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:

ClientInstallUse Case
[sqlalchemy]SQLAlchemy + SQLModelORM, modern Python
[django]Django + pytest-djangoDjango projects
[psycopg]psycopg (sync/async)Raw SQL, custom
[asyncpg]Pure async clientHigh-performance async
[all]EverythingFull 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♥️ belovedPGlite.

About

PGlite wrapper in Python for testing. Test your app with Postgres just as lite as SQLite.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp