Skip to content

Commit 4232839

Browse files
authored
Improve database management documentation (#593)
* Improve database management documentation * Link to Getting Started subsection * Untwist description of change need * Don't say please * Add folder names to EDD steps * Restore reference to finalization folders since that's been completed * Additional content changes suggested from a prior PR * Fix an oversight from #596 * Fix bungled merge from the wrong ref
1 parent 7ee3e5d commit 4232839

File tree

7 files changed

+148
-106
lines changed

7 files changed

+148
-106
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
label: "Database Migrations"
2+
position: 2

docs/contributing/database-migrations/edd.mdx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
sidebar_position: 3
3+
---
4+
15
import Tabs from "@theme/Tabs";
26
import TabItem from "@theme/TabItem";
37

@@ -130,6 +134,8 @@ actions.
130134
<Tabs>
131135
<TabItem value="first" label="Initial Migration" default>
132136

137+
Located in `util/Migrator/DbScripts`.
138+
133139
```sql
134140
-- Add Column
135141
IF COL_LENGTH('[dbo].[Customer]', 'FirstName') IS NULL
@@ -177,6 +183,8 @@ END
177183
</TabItem>
178184
<TabItem value="data" label="Transition Migration">
179185

186+
Located in `util/Migrator/DbScripts_transition`.
187+
180188
```sql
181189
UPDATE [dbo].Customer SET
182190
FirstName=FName
@@ -186,6 +194,8 @@ WHERE FirstName IS NULL
186194
</TabItem>
187195
<TabItem value="second" label="Finalization Migration">
188196

197+
Located in `util/Migrator/DbScripts_finalization`.
198+
189199
```sql
190200
-- Remove Column
191201
IF COL_LENGTH('[dbo].[Customer]', 'FName') IS NOT NULL
@@ -239,7 +249,7 @@ There are some important constraints to the implementation of the process:
239249

240250
The process to support all of these constraints is a complex one. Below is an image of a state
241251
machine that will hopefully help visualize the process and what it supports. It assumes that all
242-
database changes follow the standards that are laid out in [Migrations](./).
252+
database changes follow the standards that are laid out in [Migrations](./mssql.md).
243253

244254
---
245255

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
sidebar_position: 2
3+
---
4+
5+
# Entity Framework
6+
7+
:::info
8+
9+
For instructions on how to apply database migrations, please refer to the
10+
[Getting Started](../../getting-started/server/database/ef/index.mdx#updating-the-database)
11+
documentation.
12+
13+
:::
14+
15+
If you alter the database schema, you must create an EF migration script to ensure that EF databases
16+
keep pace with these changes. Developers must do this and include the migrations with their PR.
17+
18+
To create these scripts, you must first update your data model in `Core/Entities` as desired. This
19+
will be used to generate the migrations for each of our EF targets. Additionally, for table changes
20+
it is strongly recommended to define or update an `IEntityTypeConfiguration<T>` to accurately
21+
represent any constraints needed on the data model.
22+
23+
Once the model is updated, navigate to the `dev` directory in the `server` repo and execute the
24+
`ef_migrate.ps1` PowerShell command. You should provide a name for the migration as the only
25+
parameter:
26+
27+
```bash
28+
pwsh ef_migrate.ps1 [NAME_OF_MIGRATION]
29+
```
30+
31+
This will generate the migrations, which should then be included in your PR.

docs/contributing/database-migrations/index.md

Lines changed: 0 additions & 104 deletions
This file was deleted.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
# MSSQL
6+
7+
:::info
8+
9+
For instructions on how to apply database migrations, please refer to the
10+
[Getting Started](../../getting-started/server/database/mssql/index.md#updating-the-database)
11+
documentation.
12+
13+
:::
14+
15+
:::tip
16+
17+
We recommend reading [T-SQL Code Style](../code-style/sql.md) since it has a major impact in how we
18+
write migrations.
19+
20+
:::
21+
22+
## SQL database project
23+
24+
We use a
25+
[SDK-style SQL project](https://learn.microsoft.com/en-us/sql/azure-data-studio/extensions/sql-database-project-extension-sdk-style-projects?view=sql-server-ver16)
26+
(`.sqlproj`) to develop the database locally -- this means we have an up-to-date representation of
27+
the database in `src/Sql`, and any modifications need to be represented there as well. SDK-style SQL
28+
projects are available in Visual Studio Code that provides schema comparison and more. You may also
29+
modify the `.sql` files directly with any text editor.
30+
31+
To make a database change, start by modifying the `.sql` files in `src/Sql/dbo`. These changes will
32+
also need to be applied in a migration script. Migration scripts are located in
33+
`util/Migrator/DbScripts`.
34+
35+
You can either generate the migration scripts automatically using the _Schema Comparison_
36+
functionality or by manually writing them. Do note that the automatic method will only take you so
37+
far and it will need to be manually edited to adhere to the code styles.
38+
39+
For added safeguards we have automated linting and validation to ensure the SQL project is always up
40+
to date with the migrations.
41+
42+
The separate database definitions in `src/Sql/.../dbo` serve as a "master" reference for the
43+
intended and final state of the database at that time. This is crucial because the state of database
44+
definitions at the current moment may differ from when a migration was added in the past. These
45+
definitions act as a lint and validation step to ensure that migrations work as expected, and the
46+
separation helps maintain clarity and accuracy in database schema management and synchronization
47+
processes.
48+
49+
## Modifying the database
50+
51+
In accordance with the tenets of [Evolutionary Database Design](./edd.mdx) every change must be
52+
considered as split into two parts:
53+
54+
1. A backwards-compatible transition migration
55+
2. A non-backwards-compatible final migration
56+
57+
Most changes are entirely backwards-compatible in their final form. If this is the case, only one
58+
phase of changes is required. With the use of beta testing, partial roll-outs,
59+
[feature flags](../feature-flags.md), etc. the often-chosen path is to spread a change across
60+
several major releases with a calculated future state that can perform a "cleanup" migration that is
61+
backwards-compatible but still represents an overall-_incompatible_ change beyond the boundaries of
62+
what we need for individual release safety.
63+
64+
### Backwards compatible migration
65+
66+
1. Modify the source `.sql` files in `src/Sql/dbo`.
67+
2. Write a migration script, and place it in `util/Migrator/DbScripts`. Each script must be prefixed
68+
with the current date.
69+
70+
Tips to ensure backwards compatibility:
71+
72+
- any existing stored procedure accepts the same input parameters and that new parameters have
73+
nullable defaults
74+
- when a column is renamed the existing stored procedures first check (coalesce) the new location
75+
before falling back to the old location
76+
- continued updating of the old data columns since in case of a rollback no data should be lost
77+
78+
### Non-backwards compatible migration
79+
80+
These changes should be written from the perspective of "all data has been migrated" and any old
81+
stored procedures that were kept around for backwards compatibility should be removed. Any logic for
82+
syncing old and new data should also be removed in this step.
83+
84+
Since the `dbo` schema represents the current state we need to introduce a "future" state that we
85+
will call `dbo_finalization`.
86+
87+
1. Copy the relevant `.sql` files from `src/Sql/dbo` to `src/Sql/dbo_finalization`.
88+
2. Remove the backwards compatibility logic that is no longer needed e.g. dual reads and writes to
89+
columns.
90+
3. Write a new Migration and place it in `src/Migrator/DbScripts_finalization`. Name it
91+
`YYYY-0M-FinalizationMigration.sql`.
92+
- Typically migrations are designed to be run in sequence. However since the migrations in
93+
`DbScripts_finalization` can be run out of order, care must be taken to ensure they remain
94+
compatible with the changes to `DbScripts`. In order to achieve this we only keep a single
95+
migration, which executes all backwards incompatible schema changes.
96+
97+
Upon execution any finalization scripts will be [automatically moved](./edd.mdx#online-environments)
98+
for proper history.

docs/getting-started/server/database/ef/index.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,8 @@ existing databases if you have not already. If these settings are not present at
263263
With connection strings applied to your projects: ensure your databases are all migrated using
264264
`pwsh server/dev/migrate.ps1 --all`. Then you can run EF tests from the
265265
`test/Infrastructure.IntegrationTest` folder using `dotnet test`.
266+
267+
# Modifying the database
268+
269+
The process for modifying the database is described in
270+
[Migrations](./../../../../contributing/database-migrations/ef.md).

docs/getting-started/server/database/mssql/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ of your database.
2323
## Modifying the database
2424

2525
The process for modifying the database is described in
26-
[Migrations](./../../../../contributing/database-migrations/).
26+
[Migrations](./../../../../contributing/database-migrations/mssql.md).

0 commit comments

Comments
 (0)