Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
4474cc0
feat(postgres): add named-query CLI subcommand
vistart Apr 18, 2026
2147676
feat(backend): add named-procedure CLI subcommand
vistart Apr 19, 2026
aebe467
Add CLI tests for named-query and named-procedure subcommands
vistart Apr 19, 2026
7919cb3
feat(postgres): use custom epilog for named-query/procedure CLI
vistart Apr 20, 2026
96b0427
feat(backend): add ConcurrencyAware for PostgreSQL
vistart Apr 20, 2026
3bf5ffd
test(backend): add ConcurrencyAware protocol tests for PostgreSQL
vistart Apr 20, 2026
d45ca22
fix: update async marker for pytest-asyncio 1.3.0 compatibility
vistart Apr 20, 2026
e9834ee
Add CreateExtensionExpression and DropExtensionExpression DDL classes
vistart Apr 21, 2026
48fd065
Add multi-arch PostgreSQL image with all extensions
vistart Apr 21, 2026
6024a93
test(postgres): add protocol conformance tests
vistart Apr 22, 2026
6f1b025
fix(tests): remove AsyncIntrospectionSupport exclusion
vistart Apr 22, 2026
91cea21
refactor(backend): move threadsafety to PostgresBackendMixin
vistart Apr 23, 2026
4cfb2c1
feat(named-connection): unify handle_info config resolution and add t…
vistart Apr 23, 2026
c5ffc6e
fix(tests): remove __init__.py from named_connection test directory
vistart Apr 23, 2026
790885d
feat(extensions): enhance PostgreSQL extension detection with availab…
vistart Apr 23, 2026
4703773
fix(extensions): detect available extensions from pg_available_extens…
vistart Apr 23, 2026
995941d
feat(introspect): sort extensions by name
vistart Apr 23, 2026
67eba91
feat(extensions): add Protocol and Mixin for 17 new PostgreSQL extens…
vistart Apr 23, 2026
7910c84
feat(examples): add citext extension example
vistart Apr 23, 2026
bec31bf
feat(examples): add fuzzystrmatch and citext extension examples
vistart Apr 23, 2026
4693db4
feat(examples): add uuid_ossp and hstore extension examples
vistart Apr 23, 2026
88deb94
feat: simplify named connection API and add PostgreSQL CLI tests
vistart Apr 24, 2026
9883d4c
feat: integrate named-connection subcommand into PostgreSQL CLI
vistart Apr 24, 2026
f1e0451
feat: add PostgreSQL named connection examples
vistart Apr 24, 2026
5e0dced
fix(extensions): align Protocol and Mixin interfaces for 4 extensions
vistart Apr 24, 2026
b7816bc
feat(extensions): supplement format_* methods and Protocol signatures…
vistart Apr 24, 2026
50d1f9a
test(extensions): add test skip mechanism and unit tests for 20 exten…
vistart Apr 24, 2026
96ad6b7
test(extensions): add integration tests for 8 extensions
vistart Apr 24, 2026
f936287
feat(examples): add 8 extension usage examples
vistart Apr 24, 2026
26d7a28
feat(extensions): add postgis_raster and pgrouting Protocol/Mixin, up…
vistart Apr 24, 2026
5f116c1
refactor(examples): replace raw SQL with expression API in extension …
vistart Apr 24, 2026
0f01c8b
fix(postgres): remove RawSQLExpression from extension examples and fi…
vistart Apr 24, 2026
5ec26f6
refactor(postgres): modularize CLI from monolithic __main__.py to cli…
vistart Apr 24, 2026
c1b0647
fix(postgres): remove tests. prefix from module paths, add tests to P…
vistart Apr 26, 2026
348a2fe
refactor(backend): align expression system with three architectural p…
vistart Apr 26, 2026
641af24
fix(tests): correct UUID v1 regex pattern to match standard 8-4-4-4-1…
vistart Apr 26, 2026
eb56b98
fix(tests): add derivation pairs to protocol non-overlap exclusions
vistart Apr 26, 2026
70b9c59
fix(protocols): add @runtime_checkable to PostgresAdvisoryLockSupport…
vistart Apr 26, 2026
cfbfcf9
fix(backend): convert ? placeholders to %s for psycopg in _prepare_sq…
vistart Apr 26, 2026
61ead2c
refactor(backend): remove _convert_qmark_to_format fallback from Post…
vistart Apr 26, 2026
4c2f4d3
fix(dialect): handle base ForUpdateClause without strength attribute …
vistart Apr 26, 2026
df679bd
ci: install testsuite from git branch release/v1.0.0.dev12
vistart Apr 26, 2026
a5a4b5c
refactor(backend): use in_transaction property instead of direct _tra…
vistart Apr 26, 2026
820b078
ci: install rhosocial-activerecord from git branch release/v1.0.0.dev25
vistart Apr 27, 2026
53f63de
ci: add postgres-exts service container for extension testing
vistart Apr 27, 2026
195b185
chore: add changelog fragment for PR #32
vistart Apr 27, 2026
a2ee532
refactor(backend): extract shared non-I/O methods into mixins for syn…
vistart Apr 27, 2026
6715e06
docs(pool): add PostgreSQL connection pool stress test examples
vistart Apr 27, 2026
e671ae1
fix: MRO ordering for ExplainBackendMixin and Windows event loop comp…
vistart Apr 27, 2026
4b141c2
refactor(named_procedure): update CLI to use simplified runner.run() API
vistart Apr 28, 2026
0200f0f
chore: resolve ruff warnings and add F401 fixes
vistart Apr 28, 2026
0c48487
feat(postgres): add schema namespace support for PostgreSQL backend (…
vistart Apr 30, 2026
cb8b3a4
feat(postgres): add SQL injection security fixes for PostgreSQL dialect
vistart Apr 30, 2026
326f179
ci: use PyPI source for testsuite dependency
vistart May 1, 2026
3469c4e
ci: use PyPI source for activerecord dependency
vistart May 1, 2026
cbd4cdd
fix(postgres): support array data types in _validate_data_type
vistart May 1, 2026
032ce6e
docs: update CHANGELOG for v1.0.0.dev12
vistart May 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
35 changes: 29 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,19 @@ jobs:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
# Options to wait for postgres to be healthy before starting the job
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
postgres-exts:
image: vistart/postgres-exts:${{ matrix.postgres-version }}
env:
POSTGRES_DB: test_db
POSTGRES_USER: root
POSTGRES_PASSWORD: password
ports:
- 5433:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
Expand All @@ -65,10 +77,10 @@ jobs:
pip install -r requirements.txt
pip install -r requirements-dev.txt

- name: Install activerecord and testsuite from PyPI
- name: Install activerecord and testsuite from PyPI/git
run: |
pip install rhosocial-activerecord==1.0.0.dev24
pip install rhosocial-activerecord-testsuite==1.0.0.dev11
pip install rhosocial-activerecord==1.0.0.dev25
pip install rhosocial-activerecord-testsuite==1.0.0.dev12

- name: Create postgres scenario config
run: |
Expand All @@ -80,6 +92,12 @@ jobs:
database: test_db
username: root
password: password
postgres_exts:
host: 127.0.0.1
port: 5433
database: test_db
username: root
password: password
EOF
echo "POSTGRES_SCENARIOS_CONFIG_PATH=$(pwd)/postgres_scenarios.yaml" >> $GITHUB_ENV

Expand All @@ -95,17 +113,22 @@ jobs:
sleep 2
done
echo "postgres is ready!"
until pg_isready -h 127.0.0.1 -p 5433 -U root; do
echo "Waiting for postgres-exts..."
sleep 2
done
echo "postgres-exts is ready!"

- name: Run tests (skip for postgres 18)
if: matrix.postgres-version != '18'
run: |
export PYTHONPATH=src
export PYTHONPATH=src:tests
python -m pytest tests/ --tb=short

- name: Run tests with coverage (only for postgres 18)
if: matrix.postgres-version == '18'
run: |
export PYTHONPATH=src
export PYTHONPATH=src:tests
pip install codecov
coverage run --source=src -m pytest tests/ --tb=short
coverage xml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,4 @@ htmlcov/
# Claude Code temporary files (local only)
.claude/tmp/
.claude/plans/
.claude/plan/
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
## [v1.0.0.dev12] - 2026-05-01

### Added

- Added named query and named procedure CLI subcommands for PostgreSQL backend. Added ConcurrencyAware protocol implementation for PostgreSQL. Added named connection support with PostgreSQL CLI integration. Added comprehensive extension support with Protocol/Mixin definitions for 29 PostgreSQL extensions, CreateExtensionExpression/DropExtensionExpression DDL classes, and extension availability detection. ([#32](https://github.com/rhosocial/python-activerecord-postgres/issues/32))
- Added schema namespace support for PostgreSQL backend, including get_default_schema() method, schema-aware column formatting with alias handling, and support for multiple PostgreSQL extensions (PostGIS, pgvector, UUID, hstore). ([#33](https://github.com/rhosocial/python-activerecord-postgres/issues/33))



### Changed

- Aligned expression system with three architectural principles. Modularized CLI from monolithic __main__.py to cli/ subpackage. Moved threadsafety to PostgresBackendMixin. Removed _convert_qmark_to_format fallback (now uses proper dialect placeholder conversion). Changed CI to install rhosocial-activerecord from git branch release/v1.0.0.dev25. Added postgres-exts service container for extension testing in CI. ([#32](https://github.com/rhosocial/python-activerecord-postgres/issues/32))



### Fixed

- Fixed ? → %s placeholder conversion for psycopg in _prepare_sql_and_params. Fixed ForUpdateClause handling without strength attribute. Fixed @runtime_checkable missing on PostgresAdvisoryLockSupport and PostgresMultirangeSupport. Fixed UUID v1 regex pattern to match standard 8-4-4-4-12 format. Fixed async marker for pytest-asyncio 1.3.0 compatibility. ([#32](https://github.com/rhosocial/python-activerecord-postgres/issues/32))


## [v1.0.0.dev11] - 2026-04-17

### Added
Expand Down
81 changes: 81 additions & 0 deletions docker/postgres-all-ext/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# docker/postgres-all-ext/Dockerfile
# Multi-arch Dockerfile for PostgreSQL with all extensions
#
# Supported architectures: linux/amd64, linux/arm64, linux/ppc64le, linux/s390x
# Supported PostgreSQL versions: 14, 15, 16, 17, 18
#
# Usage:
# docker build -t postgres-all-ext:16 .
# docker run -e POSTGRES_PASSWORD=secret postgres-all-ext:16
#
# Build arguments:
# PG_VERSION: PostgreSQL version (default: 16)
# POSTGIS_VERSION: PostGIS version (default: 3.4)
# PGVECTOR_VERSION: pgvector version (default: 0.8.0)
#
# Build example:
# docker build --build-arg PG_VERSION=16 -t postgres-all-ext:16 .
#

ARG PG_VERSION=16
FROM postgres:${PG_VERSION}-bookworm

LABEL maintainer="rhosocial"
LABEL org.opencontainers.image.description="PostgreSQL with all common extensions for testing"
LABEL org.opencontainers.image.source="https://github.com/rhosocial/python-activerecord-postgres"

# Build arguments
ARG PG_VERSION
ARG POSTGIS_VERSION=3.4
ARG PGVECTOR_VERSION=0.8.0

# Environment variables
ENV PG_MAJOR=${PG_VERSION} \
POSTGIS_MAJOR=${POSTGIS_VERSION} \
PGVECTOR_VERSION=${PGVECTOR_VERSION}

# Install all extensions
# Note: bookworm is Debian-based with multi-arch support
RUN apt-get update && apt-get install -y --no-install-recommends \
# PostGIS (spatial database extension)
postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR} \
postgresql-${PG_MAJOR}-postgis-${POSTGIS_MAJOR}-scripts \
\
# pgvector (vector similarity search)
postgresql-${PG_MAJOR}-pgvector \
\
# earthdistance (great-circle distance calculations)
# Requires cube extension as dependency
postgresql-${PG_MAJOR}-cube \
postgresql-${PG_MAJOR}-earthdistance \
\
# Additional contrib extensions for comprehensive testing
postgresql-${PG_MAJOR}-uuid-ossp \
postgresql-${PG_MAJOR}-pg-trgm \
postgresql-${PG_MAJOR}-hstore \
\
# Utilities
ca-certificates \
curl \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean

# Copy initialization scripts
COPY docker-entrypoint-initdb.d/ /docker-entrypoint-initdb.d/
RUN chmod 755 /docker-entrypoint-initdb.d/*.sh /docker-entrypoint-initdb.d/*.sql 2>/dev/null || true

# Expose default port
EXPOSE 5432

# Default environment variables
ENV POSTGRES_DB=test_db \
POSTGRES_USER=root \
POSTGRES_PASSWORD=password

# Health check
HEALTHCHECK --interval=10s --timeout=5s --retries=5 \
CMD pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB} || exit 1

# Use default postgres entrypoint
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["postgres"]
172 changes: 172 additions & 0 deletions docker/postgres-all-ext/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# PostgreSQL with All Extensions

多架构 PostgreSQL Docker 镜像,包含所有常见扩展,用于测试 python-activerecord-postgres 项目。

## 支持的架构

- linux/amd64
- linux/arm64
- linux/ppc64le
- linux/s390x

## 支持的 PostgreSQL 版本

- PostgreSQL 14
- PostgreSQL 15
- PostgreSQL 16
- PostgreSQL 17
- PostgreSQL 18

## 预装的扩展

### 内置扩展 (contrib)

| 扩展 | 版本 | 说明 |
|-------|-----|------|
| uuid-ossp | 1.1 | UUID 生成函数 |
| pgcrypto | 1.3/1.4 | 加密函数 |
| ltree | 1.1~1.3 | 层级数据结构 |
| intarray | 1.2~1.5 | 整数数组操作符 |
| tablefunc | 1.0 | 表函数 (crosstab) |
| pg_trgm | 1.3~1.6 | 三元组相似度 |
| hstore | 1.4~1.8 | 键值存储 |
| cube | 1.2~1.5 | 多维立方体 |
| earthdistance | 1.1~1.3 | 地球距离 |
| pg_stat_statements | 1.4~1.12 | 查询统计 |

### 第三方扩展

| 扩展 | 版本 | 说明 |
|-------|-----|------|
| postgis | 3.4 | 空间数据库 |
| postgis_topology | 3.4 | PostGIS 拓扑 |
| postgis_tiger_geocoder | 3.4 | 地理编码 |
| vector | 0.8.0 | 向量相似度搜索 |

## 快速开始

### 使用预构建镜像

```bash
# 运行容器
docker run -d \
--name postgres-all-ext \
-e POSTGRES_PASSWORD=password \
-e POSTGRES_DB=test_db \
-p 5432:5432 \
postgres:16

# 或者使用 docker-compose
docker compose up -d
```

### 构建本地镜像

```bash
# 进入目录
cd docker/postgres-all-ext

# 构建默认版本 (16)
./build.sh

# 构建所有版本
./build.sh all

# 构建特定版本
./build.sh 16
```

## 环境变量

| 变量 | 默认值 | 说明 |
|-----|-------|------|
| POSTGRES_USER | root | 数据库用户 |
| POSTGRES_PASSWORD | password | 数据库密码 |
| POSTGRES_DB | test_db | 数据库名称 |

## 验证扩展

```bash
# 连接数据库
docker exec -it postgres-all-ext psql -U root -d test_db

# 查看已安装的扩展
SELECT extname, extversion FROM pg_extension ORDER BY extname;

# 测试 postgis
SELECT postgis_version();

# 测试 pgvector
SELECT '[-1,0,1]'::vector;

# 测试 pg_trgm
SELECT similarity('hello', 'helo');
```

## 构建参数

| 参数 | 默认值 | 说明 |
|-----|-------|------|
| PG_VERSION | 16 | PostgreSQL 主版本 |
| POSTGIS_VERSION | 3.4 | PostGIS 版本 |
| PGVECTOR_VERSION | 0.8.0 | pgvector 版本 |

## 目录结构

```
docker/postgres-all-ext/
├── Dockerfile # 多架构构建文件
├── docker-compose.yml # Compose 配置
├── build.sh # 构建脚本
├── README.md # 本文件
└── docker-entrypoint-initdb.d/
└── init-extensions.sh # 扩展初始化脚本
```

## GitHub Actions

可以使用 GitHub Actions 构建多架构镜像:

```yaml
# .github/workflows/build.yml
name: Build PostgreSQL Images

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
pg_version: [14, 15, 16, 17, 18]
steps:
- uses: actions/checkout@v4
- uses: docker/build-push-action@v5
with:
context: docker/postgres-all-ext
push: false
tags: postgres-all-ext:${{ matrix.pg_version }}
build-args: |
PG_VERSION=${{ matrix.pg_version }}
```

## 注意事项

1. **架构支持**: Debian bookworm 原生支持 amd64, arm64; ppc64le 和 s390x 需要额外配置
2. **版本兼容性**: PostGIS 3.4 支持 PostgreSQL 13-16; PostgreSQL 17+ 需要 PostGIS 3.5+
3. **资源限制**: 建议至少 2GB 内存
4. **数据持久化**: 使用 docker volume 持久化数据

## License

继承 PostgreSQL 和各扩展的许可证

## 参考

- [PostgreSQL Docker](https://github.com/docker-library/postgres)
- [PostGIS Docker](https://github.com/postgis/docker-postgis)
- [pgvector](https://github.com/pgvector/pgvector)
- [PostgreSQL contrib](https://www.postgresql.org/docs/current/contrib.html)
Loading
Loading