|
| 1 | +# Writing Migrations |
| 2 | + |
| 3 | +## Adding a New Table |
| 4 | + |
| 5 | +Before writing the Django migration, you must first modify the following files: |
| 6 | + |
| 7 | +#### datamodel.py |
| 8 | +Add your new table and relationships. Follow the capitalization style used in the existing tables closely. |
| 9 | +Each new table increments the `tableId` by 1. Tables exclusive to Specify 7 start at TableID 1000. |
| 10 | + |
| 11 | +Follow how the id field is capitalized by other tables, otherwise it will show up on schema config. |
| 12 | + |
| 13 | +#### models.py |
| 14 | +Add class to models.py (`specifyweb\specify\models.py` for most tables, you may put it in a different app if your table fits better there). |
| 15 | +Generally only the first character is capitalized in the class name, but there are some exceptions (probably unintentional). Just keep it consistent with the name you put in models_by_table_id.py later. |
| 16 | + |
| 17 | +#### types.ts |
| 18 | +In: `components/DataModel/types.ts` |
| 19 | +Read the comment to regenerate the schema. |
| 20 | + |
| 21 | +#### models_by_table_id.py |
| 22 | +Add the table name to model_names_by_table_id and model_names_by_app. |
| 23 | +Make sure the capitalization matches what you used on models.py. |
| 24 | +- Note: Attachment tables are identified by having exactly "attachment" at the end, no capital. |
| 25 | + |
| 26 | +You may now proceed onto generating the migration. |
| 27 | + |
| 28 | +## Generating New Migrations |
| 29 | +Generate the Django migration to create the table (generated from the specification in models.py). |
| 30 | +Run the following command (assuming you're using docker): |
| 31 | +`docker exec specify7-specify7-1 ve/bin/python manage.py makemigrations` |
| 32 | + |
| 33 | +Navigate to the newly created file and add extra operations if you need to. |
| 34 | +Edit the generated migration to allow for reverting if you added any additional functionality. |
| 35 | + |
| 36 | +Additional functionality includes adding the new table to the schema config, which you probably want. |
| 37 | +To add the new table's fields to the schema config, add something similar to the following: |
| 38 | +```python |
| 39 | +MIGRATION_0007_TABLES = [ |
| 40 | + ('SpDataSetAttachment', 'An attachment temporarily associated with a Specify Data Set for use in a WorkBench upload.') |
| 41 | +] |
| 42 | + |
| 43 | +MIGRATION_0007_FIELDS = { |
| 44 | + 'Spdataset': ['spDataSetAttachments'] |
| 45 | +} |
| 46 | + |
| 47 | +def apply_migration(apps, schema_editor): |
| 48 | + # Update Schema config |
| 49 | + Discipline = apps.get_model('specify', 'Discipline') |
| 50 | + for discipline in Discipline.objects.all(): # New SpDataSetAttachment table |
| 51 | + for table, desc in MIGRATION_0007_TABLES: |
| 52 | + update_table_schema_config_with_defaults(table, discipline.id, desc, apps) |
| 53 | + for discipline in Discipline.objects.all(): # New relationship Spdataset -> SpDataSetAttachment |
| 54 | + for table, fields in MIGRATION_0007_FIELDS.items(): |
| 55 | + for field in fields: |
| 56 | + update_table_field_schema_config_with_defaults(table, discipline.id, field, apps) |
| 57 | +``` |
| 58 | +The following function reverses it: |
| 59 | +```python |
| 60 | +def revert_migration(apps, schema_editor): |
| 61 | + # Revert Schema config changes |
| 62 | + for table, _ in MIGRATION_0007_TABLES: # Remove SpDataSetAttachment table |
| 63 | + revert_table_schema_config(table, apps) |
| 64 | + for table, fields in MIGRATION_0007_FIELDS.items(): # Remove relationship Spdataset -> SpDataSetAttachment |
| 65 | + for field in fields: |
| 66 | + revert_table_field_schema_config(table, field, apps) |
| 67 | +``` |
| 68 | +This is handled by adding these functions to the operations at the bottom of the file |
| 69 | +```python |
| 70 | +migrations.RunPython(apply_migration, revert_migration, atomic=True) |
| 71 | +``` |
| 72 | + |
| 73 | +#### Update datamodel.json |
| 74 | +Update datamodel.json. |
| 75 | +Regenerate by going to `http://localhost/context/datamodel.json` |
| 76 | + |
| 77 | +#### Update tests |
| 78 | +These front-end tests may now fail: |
| 79 | +`\specify7\specifyweb\frontend\js_src\lib\components\DataModel\__tests__\resource.test.ts` |
| 80 | + |
| 81 | +Follow the instructions in the comment to regenerate uniqueFields.json. |
| 82 | +```typescript |
| 83 | +/** |
| 84 | + * If this test breaks, uniqueFields.json needs to be regenerated. |
| 85 | + * 1. Go to the dev console on the browser |
| 86 | + * 2. Run the function _getUniqueFields() |
| 87 | + * 3. Paste the text into uniqueFields.json and format with prettier |
| 88 | + */ |
| 89 | +``` |
| 90 | + |
| 91 | +Update front-end test snapshots to fix the rest of the tests: |
| 92 | +`npm run unitTests -- -u` |
| 93 | + |
| 94 | +#### Run tests |
| 95 | +Run the front-end tests to make sure everything works. |
| 96 | +`npm t` |
0 commit comments