Ensure all migrations use schema defaults#8329
Conversation
This commit fixes two issues: 1. Defines a SchemaWriter class that abstracts a lot of the logic when checking for and creating Splocalecontainer, Splocalecontaineritem, and Splocaleitemstr records. 1a. This refactor also eliminates a lot of redundant database hits and tries to optimize the case when lots of Schema Config records are being created sequentially. 2. For the Schema Config creation helpers, we now introduce another layer of defaults: the schema_localization_en.json file. Previously, the helpers would fallback to modifications on the table or field name when generating the localized strings. Now we also check the default schema_localization_en.json file
Also perform some optimizations to migrations that iterate over all disciplines
📝 WalkthroughWalkthroughSchema configuration handling now uses cached, discipline-aware defaults and builder-based persistence. Migration callers pass explicit discipline identifiers and types, schema readers enforce deterministic lookups, and tests validate persisted configuration through integration-style assertions. ChangesSchema configuration workflow
Sequence Diagram(s)sequenceDiagram
participant MigrationCommand
participant SchemaDefaults
participant SchemaWriter
participant SchemaReader
participant Database
MigrationCommand->>SchemaDefaults: load defaults for discipline_type
SchemaDefaults-->>MigrationCommand: merged schema defaults
MigrationCommand->>SchemaWriter: update table or field configuration
SchemaWriter->>Database: persist containers, fields, and localized strings
SchemaReader->>Database: read persisted schema configuration
Database-->>SchemaReader: localized table and field records
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 3❌ Failed checks (1 warning, 2 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…nfig_with_defaults
g1rly-c0d3r
left a comment
There was a problem hiding this comment.
Testing instructions
-
Ensure that the Table Labels, Descriptions, and Hidden values are correct for PaleoContext, CollectionObject, Loan, CollectionObjectGroup, TectonicUnit, etc.(any table which is modified in the Schema Config as part of migrations: I can compile a complete list if required).
-
Create a Discipline with a type of "fish" and ensure that the field labels and descriptions for the following fields are correct:
- Ensure existing Schema Config edits/customizations are not lost on startup
Looks good, all labels were correct!
emenslin
left a comment
There was a problem hiding this comment.
-
Ensure that the Table Labels, Descriptions, and Hidden values are correct for PaleoContext, CollectionObject, Loan, CollectionObjectGroup, TectonicUnit, etc.(any table which is modified in the Schema Config as part of migrations: I can compile a complete list if required).
-
Create a Discipline with a type of "fish" and ensure that the field labels and descriptions for the following fields are correct:
-
Ensure existing Schema Config edits/customizations are not lost on startup
Overall looks good but I did run into a few possible problems. I noticed that the Catalog Number format is always set to CatalogNumberString (current, invalid value) no matter what format is selected in guided setup. Although I know that the catalog number format still works, I could see this being very misleading to a user.
Additionally even with a geo discipline selected the Chronostrat and Lithostrat tables are hidden in the schema config by default, but Paleo/Geo Context and Tectonic Unit are visible. All of these should probably be visible for paleo/geo disciplines.
07-22_10.41.mp4
There was a problem hiding this comment.
- On a blank database created through Guided Setup, the tested table captions, descriptions, and hidden settings matched schema_localization_en.json.
- Created a Fish discipline and verified the expected labels and descriptions for the listed fields.
- On the existing database, Schema Config customizations were preserved after restarting Specify.
I found no issues during these checks. Approved.
|
Thank you all for the reviews! 👏
@emenslin, I "fixed" the The commit which sets the default catalogNumber (in the Schema Config) to None: c40773f The commits are currently on |

Fixes #8307
The most direct cause of the #8307 was that migrations were not using the schema_localization_en.json file.
This meant that explicit Django migrations that worked with the Schema Config would not "default" to our expected Schema Defaults.
Take for example the migration for
specify/0020:, which would trigger an update for thePaleoContext -> tectonicUnitrelationship in the Schema Config:specify7/specifyweb/specify/migration_utils/migration_helpers/helper_0020_add_tectonicunit_to_pc_in_schema_config.py
Lines 7 to 9 in 27cb105
Specify would first attempt to check whether the PaleoContext table already existed in the Schema Config and create the table if it didn't exist:
specify7/specifyweb/specify/migration_utils/update_schema_config.py
Lines 1388 to 1389 in 4c80482
specify7/specifyweb/specify/migration_utils/update_schema_config.py
Lines 513 to 516 in 4c80482
The Issue here is that we are generally expecting PaleoContext to have the description defined in the default schema file:
specify7/config/common/schema_localization_en.json
Lines 4589 to 4590 in 4c80482
However, the table will be created with the "heuristically" generated default description and not look at the Schema Defaults file.
This PR seeks to address this Issue and have all functions that interact with the Schema Config via the helper functions go through an additional layer of defaults: those defined in the JSON file.
In addition, this PR simplifies the Schema Configuration interface for the application.
Primarily (from an internal Slack message. Also see e258b74):
Because the changes are relatively significant, I measured the proportional performance impact of these changes on a variety of databases.
The tests are not performed on a production-ready instance of Specify (using the production image/Gunicorn), but the effects should be relatively proportional.
In terms of speed, I measured the total start up time for Specify (which is largely dominated by the time it takes to apply the Schema Defaults) on my local machine, and measured the following results:
This shows a massive improvement in how long it takes Specify to apply and/or check a potentially large amount of Schema Configuration records. On average, I saw a 6x improvement in speed.
Knowing it would likely be worse/higher, I also measured the memory impact of these changes. Below are some measurements taken after two actions in Specify which measure the PSS of the Specify process (captured via smem) after each action.
While there is on average a negative change in memory impact thus far, the change seems small at the moment (in the worse case when profiling a sufficiently large database taking an extra ~2 MB of space).
If this proves to be a concern, we can reduce this memory usage even further by tweaking the batching of queries within SchemaWriter.
Checklist
self-explanatory (or properly documented)
specify7/specifyweb/specify/management/commands/run_key_migration_functions.py
Line 50 in ea04665
Testing instructions
Summary by CodeRabbit
New Features
Bug Fixes
Tests