Skip to main content

PostgreSQL Wire Protocol Server for InterSystems IRIS - Connect BI tools, Python frameworks, and PostgreSQL clients to IRIS databases

Project description

iris-pgwire: PostgreSQL Wire Protocol for InterSystems IRIS

License: MIT Python 3.11+ Docker InterSystems IRIS

Access IRIS through the entire PostgreSQL ecosystem - Connect BI tools, Python frameworks, data pipelines, and thousands of PostgreSQL-compatible clients to InterSystems IRIS databases with zero code changes.


📊 Why This Matters

Verified compatibility with PostgreSQL clients across 8 languages - no IRIS-specific drivers needed:

  • Tested & Working: Python (psycopg3, asyncpg), Node.js (pg), Java (JDBC), .NET (Npgsql), Go (pgx), Ruby (pg gem), Rust (tokio-postgres), PHP (PDO)
  • BI Tools: Apache Superset, Metabase, Grafana (use standard PostgreSQL driver)
  • ORMs: SQLAlchemy, Prisma, Sequelize, Hibernate, Drizzle

Connection: postgresql://localhost:5432/USER - that's it!


🚀 Quick Start

Docker (Fastest - 60 seconds)

git clone https://github.com/intersystems-community/iris-pgwire.git
cd iris-pgwire
docker-compose up -d

# Test it works
psql -h localhost -p 5432 -U _SYSTEM -d USER -c "SELECT 'Hello from IRIS!'"

Python Package

pip install iris-pgwire psycopg[binary]

# Configure IRIS connection
export IRIS_HOST=localhost IRIS_PORT=1972 IRIS_USERNAME=_SYSTEM IRIS_PASSWORD=SYS IRIS_NAMESPACE=USER

# Start server
python -m iris_pgwire.server

ZPM Installation (Existing IRIS)

For InterSystems IRIS 2024.1+ with ZPM package manager:

// Install the package
zpm "install iris-pgwire"

// Start the server manually
do ##class(IrisPGWire.Service).Start()

// Check server status
do ##class(IrisPGWire.Service).ShowStatus()

From terminal:

# Install
iris session IRIS -U USER 'zpm "install iris-pgwire"'

# Start server
iris session IRIS -U USER 'do ##class(IrisPGWire.Service).Start()'

First Query

import psycopg

with psycopg.connect('host=localhost port=5432 dbname=USER') as conn:
    cur = conn.cursor()
    cur.execute('SELECT COUNT(*) FROM YourTable')
    print(f'Rows: {cur.fetchone()[0]}')

✅ Client Compatibility

171/171 tests passing across 8 programming languages:

Language Verified Clients Test Coverage
Python psycopg3, asyncpg, SQLAlchemy 100% (21 tests)
Node.js pg (node-postgres) 100% (17 tests)
Java PostgreSQL JDBC 100% (27 tests)
.NET Npgsql 100% (15 tests)
Go pgx v5 100% (19 tests)
Ruby pg gem 100% (25 tests)
Rust tokio-postgres 100% (22 tests)
PHP PDO PostgreSQL 100% (25 tests)

ORMs & BI Tools: Prisma, Sequelize, Hibernate, Drizzle, Apache Superset, Metabase, Grafana

See Client Compatibility Guide for detailed testing results and ORM setup examples.


🎯 Key Features

  • pgvector Syntax: Use familiar <=> and <#> operators - auto-translated to IRIS VECTOR_COSINE/DOT_PRODUCT. HNSW indexes provide 5× speedup on 100K+ vectors. See Vector Operations Guide

  • ORM & DDL Compatibility: Automatic publicSQLUser schema mapping and PostgreSQL DDL transformations (stripping fillfactor, GENERATED columns, USING btree, etc.) for seamless migrations. See DDL Compatibility Guide

  • Enterprise Security: SCRAM-SHA-256, OAuth 2.0, IRIS Wallet authentication. Industry-standard security matching PgBouncer, YugabyteDB. See Deployment Guide

  • Performance: ~4ms protocol overhead, dual backend (DBAPI/Embedded), async SQLAlchemy support. See Performance Benchmarks


💻 Usage Examples

Command-Line (psql)

# Connect to IRIS via PostgreSQL protocol
psql -h localhost -p 5432 -U _SYSTEM -d USER

# Simple queries
SELECT * FROM MyTable LIMIT 10;

# Vector similarity search
SELECT id, VECTOR_COSINE(embedding, TO_VECTOR('[0.1,0.2,0.3]', DOUBLE)) AS score
FROM vectors
ORDER BY score DESC
LIMIT 5;

Python (psycopg3)

import psycopg

with psycopg.connect('host=localhost port=5432 dbname=USER user=_SYSTEM password=SYS') as conn:
    # Simple query
    with conn.cursor() as cur:
        cur.execute('SELECT COUNT(*) FROM MyTable')
        count = cur.fetchone()[0]
        print(f'Total rows: {count}')

    # Parameterized query
    with conn.cursor() as cur:
        cur.execute('SELECT * FROM MyTable WHERE id = %s', (42,))
        row = cur.fetchone()

    # Vector search with parameter binding
    query_vector = [0.1, 0.2, 0.3]  # Works with any embedding model
    with conn.cursor() as cur:
        cur.execute("""
            SELECT id, VECTOR_COSINE(embedding, TO_VECTOR(%s, DOUBLE)) AS score
            FROM vectors
            ORDER BY score DESC
            LIMIT 5
        """, (query_vector,))
        results = cur.fetchall()

Async SQLAlchemy with FastAPI

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy import text
from fastapi import FastAPI, Depends

# Setup
engine = create_async_engine("postgresql+psycopg://localhost:5432/USER")
SessionLocal = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
app = FastAPI()

async def get_db():
    async with SessionLocal() as session:
        yield session

# FastAPI endpoint with async IRIS query
@app.get("/users/{user_id}")
async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):
    result = await db.execute(
        text("SELECT * FROM users WHERE id = :id"),
        {"id": user_id}
    )
    return result.fetchone()

📚 Documentation Index

📖 Complete Documentation → - Full navigation hub with all guides, architecture docs, and troubleshooting

Getting Started

Features & Capabilities

Architecture & Performance

Development & Reference


⚡ Production Ready

171/171 tests passing - Verified compatibility with Python, Node.js, Java, .NET, Go, Ruby, Rust, PHP PostgreSQL clients

What Works: Core protocol (queries, transactions, COPY), Enterprise auth (SCRAM-SHA-256, OAuth 2.0), pgvector operators, ORM introspection

Architecture: SSL/TLS via reverse proxy (nginx/HAProxy), OAuth 2.0 instead of Kerberos - industry patterns matching PgBouncer, YugabyteDB

See Roadmap & Limitations for details


🤝 Contributing

# Clone repository
git clone https://github.com/intersystems-community/iris-pgwire.git
cd iris-pgwire

# Install development dependencies
uv sync --frozen

# Start development environment
docker-compose up -d

# Run tests
pytest -v

Code Quality: black (formatter), ruff (linter), pytest (testing)


🔗 Links


📄 License

MIT License - See LICENSE for details


Questions? Open an issue on GitHub

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

iris_pgwire-1.2.10.tar.gz (336.8 kB view details)

Uploaded Source

Built Distribution

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

iris_pgwire-1.2.10-py3-none-any.whl (364.2 kB view details)

Uploaded Python 3

File details

Details for the file iris_pgwire-1.2.10.tar.gz.

File metadata

  • Download URL: iris_pgwire-1.2.10.tar.gz
  • Upload date:
  • Size: 336.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for iris_pgwire-1.2.10.tar.gz
Algorithm Hash digest
SHA256 6cd7cbe4d4d76271e1212e964be68f6d3a0e5e20f32f5be5b00a6464a628b12b
MD5 b9f34880481d0e10c6a72880b903a5fe
BLAKE2b-256 bf7860373ff9f3f0c1fef0bd3c11a359e9c94a61236214fa53a045da9179c66f

See more details on using hashes here.

File details

Details for the file iris_pgwire-1.2.10-py3-none-any.whl.

File metadata

  • Download URL: iris_pgwire-1.2.10-py3-none-any.whl
  • Upload date:
  • Size: 364.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for iris_pgwire-1.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 19ccecc09bca172e87aa5a126f3ba05e27fe10ed93330873cb129be951c2f598
MD5 59d651e31f564dd75541a25b9a6eacc9
BLAKE2b-256 a1f41edfe80887d621c4487d0ab50f4dd069ae9ba8d902386a5a8100ac8d7800

See more details on using hashes here.

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