Go to file
2026-08-16 10:32:42 +02:00
.hop [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
bootstrap [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
ddd_domain [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
Patches [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
tests [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
.gitignore [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
pyproject.toml [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00
README.md [HOP] Initial commit (release: 0.0.0) 2026-08-16 10:32:42 +02:00

ddd_domain

Database-driven application using half-orm with half-orm-dev workflow.

Database: ddd_domain Generated with: half-orm-dev==1.0.0-a32


🚀 Quick Start

Prerequisites

# Install half-orm-dev (includes half-orm)
# IMPORTANT: Install the version specified in .hop/config.
#   Replace <version> by the value of hop_version.
pip install half-orm-dev==<version>

Version requirement: This project requires half-orm-dev >= 1.0.0-a32

Clone This Project

# Clone project with automatic database setup (use git_origin in .hop/config)
half_orm dev clone <git_origin>

This will:

  • Clone the repository and checkout ho-prod branch
  • Configure database connection in /etc/half_orm/ddd_domain or ${HALFORM_CONF_DIR}/ddd_domain
  • Restore production schema from .hop/model/schema.sql
  • Generate Python ORM classes in ddd_domain/ directory

📖 Development Workflow

This project uses half-orm-dev for database versioning and patch management.

1. Create a Release

# Create new minor release (e.g., 0.17.0)
half_orm dev release create minor

# Creates ho-release/0.17.0 branch
# Creates .hop/releases/0.17.0-patches.toml

2. Create a Patch

Create patch (auto-added as candidate)

half_orm dev patch create -

Example: Create user authentication patch

half_orm dev patch create 456-user-auth

Creates ho-patch/456-user-auth branch

Creates Patches/456-user-auth/ directory


### 3. Develop Your Changes

```bash
# Add SQL migration
echo "CREATE TABLE users (id SERIAL PRIMARY KEY, username TEXT);" > Patches/456-user-auth/1-create-users.sql

# Add Python migration (optional)
cat > Patches/456-user-auth/2-seed-data.py << 'EOF'
from ddd_domain.public.users import Users

def apply(model):
    Users(username='admin').ho_insert()
EOF

# Apply patch to test database
half_orm dev patch apply

# Generated ORM classes available in ddd_domain/
from ddd_domain.public.users import Users
user = Users(username='john').ho_insert()

4. Test Your Changes

# Run tests (pytest must be configured)
pytest tests/

# half-orm-dev validates:
# - Patch SQL syntax
# - Patch idempotency (can be applied twice)
# - Test suite passes with full release context

5. Merge Patch into Release

# Merge patch (automatic validation + tests)
half_orm dev patch merge

# What happens:
# 1. Creates temp validation branch
# 2. Applies ALL staged patches + your patch
# 3. Runs pytest tests/
# 4. If tests pass → merges into ho-release/X.Y.Z
# 5. Changes patch status to "staged" in TOML
# 6. Deletes patch branch

6. Promote Release

# Stage → RC (first release candidate)
half_orm dev release promote rc

# Creates .hop/releases/0.17.0-rc1.txt snapshot
# Tags ho-release-0.17.0-rc1

# RC → Production (after validation)
half_orm dev release promote prod

# Merges into ho-prod branch
# Creates .hop/releases/0.17.0.txt
# Tags production-0.17.0
# Generates .hop/model/schema-0.17.0.sql

🔧 Common Commands

Status & Information

half_orm dev check              # Show repository state

Patch Management

half_orm dev patch create       # create a new patch for release
half_orm dev patch apply        # Apply patch to dev database
half_orm dev patch merge        # Integrate patch into release

Release Management

half_orm dev release create <level>     # Create release (patch/minor/major)
half_orm dev release promote rc         # Stage → RC
half_orm dev release promote prod       # RC → Production

Production Deployment

# On production server
half_orm dev update             # Check available releases
half_orm dev upgrade <version>  # Deploy specific version

📁 Project Structure

ddd_domain/
├── .hop/                       # half-orm-dev metadata
│   ├── config                  # Repository configuration
│   ├── model/                  # Database schemas and data
│   │   ├── schema.sql          # Current production schema (symlink)
│   │   ├── schema-X.Y.Z.sql    # Versioned schemas
│   │   ├── metadata-X.Y.Z.sql  # half_orm_meta data dumps
│   │   └── data-X.Y.Z.sql      # Reference data from @HOP:data patches
│   └── releases/               # Release tracking files
│       ├── X.Y.Z-patches.toml  # Development releases (mutable)
│       ├── X.Y.Z-rcN.txt       # Release candidates (immutable)
│       └── X.Y.Z.txt           # Production releases (immutable)
├── Patches/                    # Patch directories
│   └── <id>-<description>/     # Individual patch files
│       ├── *.sql               # SQL migrations (numbered)
│       └── *.py                # Python migrations (optional)
├── ddd_domain/             # Generated ORM package
│   └── <schema>/               # schema classes
└── tests/                      # Test suite (pytest)

🌿 Git Branch Structure

  • ho-prod: Production branch (stable, source of truth)
  • ho-release/X.Y.Z: Release integration branches (temporary)
  • ho-patch/ID: Patch development branches (temporary)

All development happens on patch branches, merged into release branches, then promoted to production.


💾 Data Persistence (@HOP:data)

For reference data that must be loaded with every database installation (lookup tables, default roles, etc.), use the @HOP:data annotation:

-- @HOP:data
-- This file will be included in model/data-X.Y.Z.sql

INSERT INTO roles (name, description)
VALUES ('admin', 'Administrator')
ON CONFLICT (name) DO NOTHING;

INSERT INTO permissions (name)
VALUES ('read'), ('write'), ('delete')
ON CONFLICT DO NOTHING;

How it works

  1. In patches: SQL files starting with -- @HOP:data contain reference data
  2. Production promote: All @HOP:data files are consolidated into model/data-X.Y.Z.sql
  3. Clone/Restore: Data files are loaded automatically after schema restoration
  4. Production upgrade: Data is inserted via normal patch application (no special handling)

Best practices

  • Use ON CONFLICT DO NOTHING or ON CONFLICT DO UPDATE for idempotency
  • Keep data files small and focused (one concern per file)
  • Number your SQL files to control execution order: 01_roles.sql, 02_permissions.sql
  • Only use for reference data, not user-generated data

Async Usage

The generated package supports both synchronous and asynchronous access to the database.

Sync

from ddd_domain.public.users import Users

user = Users(username='john').ho_get()
users = list(Users(is_active=True).ho_select())

Async

import asyncio
from ddd_domain import aconnect, adisconnect
from ddd_domain.public.users import Users

async def main():
    await aconnect()
    try:
        user = await Users(username='john').ho_aget()
        users = await Users(is_active=True).ho_aselect()
    finally:
        await adisconnect()

asyncio.run(main())

REST API (FastAPI)

from contextlib import asynccontextmanager
from fastapi import FastAPI
import ddd_domain

@asynccontextmanager
async def lifespan(app: FastAPI):
    await ddd_domain.aconnect()
    yield
    await ddd_domain.adisconnect()

app = FastAPI(lifespan=lifespan)

The async connection pool is established automatically during tests via the _async_pool fixture in tests/conftest.py.


📚 Documentation


🆘 Getting Help

half_orm dev --help             # General help
half_orm dev patch --help       # Patch commands
half_orm dev release --help     # Release commands

⚠️ Important Notes

  1. Always work on patch branches - Never commit directly to ho-prod or ho-release
  2. Test before merging - patch merge runs tests automatically
  3. Sequential releases - Only the smallest version in preparation can be promoted
  4. Idempotent patches - SQL must be replayable (use IF NOT EXISTS, etc.)
  5. Production schema - .hop/model/schema.sql is the source of truth

Generated by half-orm-dev 1.0.0-a32