Skip to main content

postgres backend implementation for rhosocial-activerecord, providing a robust and optimized postgres database support.

Project description

rhosocial-activerecord-postgres ($\rho_{\mathbf{AR}\text{-postgres}}$)

PyPI version Python Tests Coverage Status Apache 2.0 License Powered by vistart

rhosocial ActiveRecord Logo

PostgreSQL Backend for rhosocial-activerecord

Native Array & JSONB Support · Advanced Types · Sync & Async

Note: This is a backend implementation for rhosocial-activerecord. It cannot be used standalone.

Why This Backend?

1. PostgreSQL's Unique Type System

Feature PostgreSQL Backend MySQL Backend SQLite Backend
Native Arrays INTEGER[], TEXT[] ❌ Serialize to string ❌ Serialize to string
JSONB ✅ Binary JSON, indexed ✅ JSON (text-based) ⚠️ JSON1 extension
UUID ✅ Native type ⚠️ CHAR(36) ⚠️ TEXT
Range Types DATERANGE, INT4RANGE
RETURNING ✅ All operations

2. No Adapter Overhead for Arrays

Unlike databases without native arrays, PostgreSQL stores and queries arrays directly:

# PostgreSQL: Native array - no serialization needed
class Article(ActiveRecord):
    tags: list[str]  # Maps directly to TEXT[]

# MySQL/SQLite: Requires adapter
class Article(ActiveRecord):
    tags: Annotated[list[str], UseAdapter(ListToStringAdapter(), str)]

3. Powerful Array Operators

Query arrays with native PostgreSQL operators:

# Contains
Article.query().where("tags @> ARRAY[?]", ('python',)).all()

# Overlaps (any element matches)
Article.query().where("tags && ARRAY[?, ?]", ('python', 'database')).all()

# Any element equals
Article.query().where("? = ANY(tags)", ('python',)).all()

💡 AI Prompt: "Show me all PostgreSQL array operators with examples"

Quick Start

Installation

pip install rhosocial-activerecord-postgres

Basic Usage

from rhosocial.activerecord.model import ActiveRecord
from rhosocial.activerecord.backend.impl.postgres import PostgresBackend
from rhosocial.activerecord.backend.impl.postgres.config import PostgresConnectionConfig
from typing import Optional
from uuid import UUID

class User(ActiveRecord):
    __table_name__ = "users"
    id: Optional[UUID] = None  # Native UUID type
    name: str
    tags: list[str]  # Native array type
    metadata: dict  # JSONB type

# Configure
config = PostgresConnectionConfig(
    host="localhost",
    port=5432,
    database="myapp",
    username="user",
    password="password"
)
User.configure(config, PostgresBackend)

# Use
user = User(name="Alice", tags=["python", "postgres"])
user.save()

# Query with array operators
python_users = User.query().where("tags @> ARRAY[?]", ('python',)).all()

💡 AI Prompt: "How do I configure connection pooling for PostgreSQL?"

PostgreSQL-Specific Features

Array Types

Native array support without adapters:

class Article(ActiveRecord):
    __table_name__ = "articles"
    title: str
    tags: list[str]      # TEXT[]
    scores: list[int]    # INTEGER[]

# Query with array operators
Article.query().where("tags @> ARRAY[?]", ('python',)).all()
Article.query().where("? = ANY(tags)", ('database',)).all()
Article.query().where("array_length(tags, 1) > ?", (3,)).all()

See Array Type Comparison for differences with other databases.

JSONB Operations

Binary JSON with indexing support:

class Product(ActiveRecord):
    __table_name__ = "products"
    name: str
    attributes: dict  # JSONB

# Query JSONB
Product.query().where("attributes->>'brand' = ?", ("Dell",)).all()

# JSONB contains (@>)
Product.query().where("attributes @> ?", ('{"brand": "Dell"}',)).all()

UUID Type

Native UUID storage and querying:

from uuid import UUID, uuid4

class User(ActiveRecord):
    __table_name__ = "users"
    id: UUID
    name: str

user = User(id=uuid4(), name="Alice")
user.save()

Range Types

Built-in support for range types:

from datetime import date

class Booking(ActiveRecord):
    __table_name__ = "bookings"
    room_id: int
    date_range: tuple  # DATERANGE

# Query with range operators
Booking.query().where("date_range @> ?", (date(2024, 1, 15),)).all()

RETURNING Clause

Retrieve data after INSERT/UPDATE/DELETE:

# INSERT with RETURNING
user = User(name="Alice")
user.save()
print(user.id)  # Populated automatically via RETURNING

# Works for all operations (unlike MySQL)

Requirements

  • Python: 3.8+ (including 3.13t/3.14t free-threaded builds)
  • Core: rhosocial-activerecord>=1.0.0
  • Driver: psycopg>=3.2.12

PostgreSQL Version Compatibility

Feature Min Version Notes
Basic operations 8.0+ Core functionality
CTEs 8.4+ WITH clauses
Window functions 8.4+ ROW_NUMBER, RANK, etc.
RETURNING 8.2+ INSERT/UPDATE/DELETE RETURNING
JSON 9.2+ Basic JSON support
JSONB 9.4+ Binary JSON, indexed
UPSERT 9.5+ INSERT ... ON CONFLICT

Recommended: PostgreSQL 12+ for optimal feature support.

Get Started with AI Code Agents

This project supports AI-assisted development:

git clone https://github.com/rhosocial/python-activerecord-postgres.git
cd python-activerecord-postgres

Example AI Prompts

  • "How do I use array operators to query tags?"
  • "What's the difference between JSON and JSONB in PostgreSQL?"
  • "Show me how to create a GIN index on an array column"
  • "How do I use range types for scheduling?"

For Any LLM

Feed the documentation files in docs/ for context-aware assistance.

Testing

⚠️ CRITICAL: Tests MUST run serially. Do NOT use pytest -n auto or parallel execution.

# Run all tests
PYTHONPATH=src pytest tests/

# Run specific feature tests
PYTHONPATH=src pytest tests/rhosocial/activerecord_postgres_test/feature/basic/
PYTHONPATH=src pytest tests/rhosocial/activerecord_postgres_test/feature/query/

See the Testing Documentation for details.

Documentation

Comparison with Other Backends

Feature PostgreSQL MySQL SQLite
Native Arrays
JSONB (indexed) ⚠️ JSON only ⚠️ Extension
UUID Type ✅ Native ⚠️ CHAR(36) ⚠️ TEXT
Range Types
RETURNING
CTEs ✅ 8.4+ ✅ 8.0+ ✅ 3.8.3+
Full-Text Search ⚠️ FTS5

💡 AI Prompt: "When should I choose PostgreSQL over MySQL for my project?"

Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

License

Apache License 2.0 — Copyright © 2026 vistart


Built with ❤️ by the rhosocial team

GitHub · Documentation · PyPI

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

rhosocial_activerecord_postgres-1.0.0.dev3.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

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

File details

Details for the file rhosocial_activerecord_postgres-1.0.0.dev3.tar.gz.

File metadata

File hashes

Hashes for rhosocial_activerecord_postgres-1.0.0.dev3.tar.gz
Algorithm Hash digest
SHA256 6ac208eb616fa962ab8de6c068a2edd3baa9530400cc1eb24a9ad51d0c087d65
MD5 5ac813ddc6b582085e0ef62a617e02fd
BLAKE2b-256 409a0f4b3d33cb46fde72506ea01b7e5b78eca3de4a3f31558bf8e33ab2edd37

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhosocial_activerecord_postgres-1.0.0.dev3.tar.gz:

Publisher: publish.yml on rhosocial/python-activerecord-postgres

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

File details

Details for the file rhosocial_activerecord_postgres-1.0.0.dev3-py3-none-any.whl.

File metadata

File hashes

Hashes for rhosocial_activerecord_postgres-1.0.0.dev3-py3-none-any.whl
Algorithm Hash digest
SHA256 e3bf8b5febe0a88ce1f44ee03e23e447e9688b5060ce399ac6d2df8ed71d07ea
MD5 c389400dd586a6abd6f574a700386733
BLAKE2b-256 de1fe2c54b5509e382218bb5a3eb2875ee44d9087015803e2dad0684dddf6a1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rhosocial_activerecord_postgres-1.0.0.dev3-py3-none-any.whl:

Publisher: publish.yml on rhosocial/python-activerecord-postgres

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