Closes: #391 (Phase 1) - Snapshot mixin base columns into schema_document#480
Closes: #391 (Phase 1) - Snapshot mixin base columns into schema_document#480bctiemann wants to merge 3 commits into386-schema-exportfrom
Conversation
…t COT creation Add CustomObjectType._collect_base_columns() and _store_base_column_snapshot() to record the concrete columns contributed by the CustomObject mixin hierarchy (id, created, last_updated, and any future additions) at table-creation time. The snapshot is stored in schema_document["base_columns"] alongside any existing keys, preserving schema-exporter output from #386. Add migration 0009_backfill_base_columns to populate the snapshot for all existing COT tables using DB introspection, subtracting user-defined field names to isolate base columns. This is the foundation for Phase 2 (post_migrate auto-heal handler that detects and applies mixin schema drift when NetBox is upgraded). Note: migration 0009_alter_customobjecttype_version on branch 392-validate-semver-fields will need renumbering to 0010 before that PR merges.
…se_columns after creation
|
@claude /review |
|
Claude finished @bctiemann's task in 1m 55s —— View job PR Review: Closes #391 (Phase 1) - Snapshot base columns into schema_document
OverviewThis PR adds Phase 1 of the auto-heal schema upgrade mechanism: at COT birth, snapshot the mixin-contributed DB columns into Code Quality
Solid implementation. Using One minor note: the output order is determined by Django's internal field ordering (typically declaration order). The backfill migration, however, sorts by column name ( # Suggestion: sort in _collect_base_columns to match backfill ordering
return sorted([
{"name": f.name, "field_class": f.__class__.__name__, "null": f.null}
for f in model._meta.concrete_fields
if f.name not in user_field_names
], key=lambda e: e["name"])
The preservation of pre-existing Minor concern: when called during Migration Overall well-designed. A few observations:
TestsThe test suite (
One note on
SummaryThe implementation is solid and the design rationale is well-documented. The three main concerns to address before merge:
|
- Sort _collect_base_columns return value by name to match the alphabetical ordering used in the backfill migration, so both paths produce consistent snapshots - field_class is now always present in backfill entries (was conditionally absent for columns not in base_field_info); falls back to 'UnknownField' for any unrecognised column - Derive id field class from CustomObject._meta.pk.__class__.__name__ instead of hardcoding 'AutoField', handling BigAutoField installs - Use USER_TABLE_DATABASE_NAME_PREFIX constant in migration instead of duplicating the 'custom_objects_' literal - Update test to assert field_class is always present in backfilled entries Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Addressed all review issues. |
arthanson
left a comment
There was a problem hiding this comment.
merge feature and request merge to feature not 3886-schema-export
Summary
CustomObjectType._collect_base_columns()-- static method that returns the concrete DB columns contributed by theCustomObjectmixin hierarchy (e.g.id,created,last_updated), excluding user-defined field names.CustomObjectType._store_base_column_snapshot()-- writes those columns toschema_document["base_columns"]immediately after a COT table is created, preserving any other existing keys inschema_document(e.g. the schema-exporter output from Define a schema format for portable Custom Object Type definitions #386)._store_base_column_snapshot()intocreate_model()so every new COT records its base column state at birth.0009_backfill_base_columnsthat uses DB introspection to populateschema_document["base_columns"]for all existing COTs, subtracting user-defined field names to isolate the base columns.Context
This is Phase 1 of the fix for #391 ("Automatically handle Custom Object Type schema upgrades created through changes to core mixins"). The snapshot recorded here will be consumed by the Phase 2
post_migrateauto-heal handler, which will diff the stored snapshot against the currentCustomObjectmodel definition and apply any new columns to existing COT tables when NetBox is upgraded.See the strategy discussion on #391 for the full design.
Migration note
392-validate-semver-fields(PR #455) has a0009_alter_customobjecttype_versionmigration that will conflict with our0009_backfill_base_columns. That PR will need its migration renumbered to0010before it merges into the updated386-schema-export.Test plan
CollectBaseColumnsTestCase--_collect_base_columns()returnsid/created/last_updated, excludes user-defined field names, and produces entries withname/field_class/nullkeysStoreBaseColumnSnapshotTestCase-- snapshot is written toschema_document["base_columns"], existing document keys are preserved, in-memory attribute is updatedCreateModelSnapshotTestCase-- a freshly created COT hasbase_columnsinschema_documentwith the expected mandatory columnsBackfillBaseColumnsTestCase-- migration function populates existing COTs, excludes user fields, is idempotent, skips already-backfilled rows, handles multiple COTs, and produces entries with required keysGenerated with Claude Code