FerroField(index=True) works on plain columns, but ForeignKey doesn't accept index. Postgres doesn't auto-index FK columns, and most multi-tenant schemas need indexes on org_id-style FK columns for both ordinary tenant queries and (in our case) RLS policy evaluation.
Proposed API
ForeignKey(
related_name=...,
on_delete=...,
unique=False,
index=False, # <-- new
nullable='infer',
)
When index=True, autogen emits CREATE INDEX on the shadow *_id column the same way FerroField(index=True) does for plain columns. unique=True already produces an implicit unique index, so the new flag is the non-unique variant.
Acceptance criteria
ForeignKey(..., index=True) causes Alembic autogen to emit a non-unique index on the shadow *_id column.
index=False (default) keeps current behavior.
index=True + unique=True is allowed and emits both (or just the unique index, since unique implies index — implementer's call).
- Index name follows existing autogen convention.
Motivation
Same downstream project (Blueberry / RLS): every tenant-scoped table has an org_id FK that is queried on every list endpoint. We're hand-editing eight indexes into the migration today; would prefer to declare them on the model.
FerroField(index=True)works on plain columns, butForeignKeydoesn't acceptindex. Postgres doesn't auto-index FK columns, and most multi-tenant schemas need indexes onorg_id-style FK columns for both ordinary tenant queries and (in our case) RLS policy evaluation.Proposed API
When
index=True, autogen emitsCREATE INDEXon the shadow*_idcolumn the same wayFerroField(index=True)does for plain columns.unique=Truealready produces an implicit unique index, so the new flag is the non-unique variant.Acceptance criteria
ForeignKey(..., index=True)causes Alembic autogen to emit a non-unique index on the shadow*_idcolumn.index=False(default) keeps current behavior.index=True+unique=Trueis allowed and emits both (or just the unique index, since unique implies index — implementer's call).Motivation
Same downstream project (Blueberry / RLS): every tenant-scoped table has an
org_idFK that is queried on every list endpoint. We're hand-editing eight indexes into the migration today; would prefer to declare them on the model.