Setup

Create shared metadata and one project base:

from sqlalchemy import MetaData
from sqlalchemy.orm import DeclarativeBase

from codegen_database import (
    CodegenDatabaseBase,
    CodegenDatabaseConfig,
    construct_naming_conventions_dict,
)
from codegen_database.ext.chart import ChartExtension

config = CodegenDatabaseConfig(auto_discover=False).use(ChartExtension())
metadata = MetaData(
    naming_convention=construct_naming_conventions_dict(),
    info={"codegen_database_config": config},
)

class Base(CodegenDatabaseBase, DeclarativeBase):
    metadata = metadata

Ordinary model, view, materialized-view, and function classes all inherit Base. Imperative view and function constructors use Base.metadata.

Alembic

Create the config before importing models, then pass it to both lifecycle hooks:

from codegen_database.alembic.register import (
    alembic_hook,
    configure_metadata,
    process_revision_directives,
    render_item,
)
from myapp.config import config

alembic_hook(config)

from myapp.models import Base

target_metadata = Base.metadata
configure_metadata(target_metadata, config)

context.configure(
    target_metadata=target_metadata,
    include_schemas=True,
    process_revision_directives=process_revision_directives,
    render_item=render_item,
)

configure_metadata registers pg_trgm by default. Other PostgreSQL extensions are explicit metadata declarations or built-in extensions.