The project uses the Microsoft SQL Server RDBMS with TypeORM as the ORM.
As of January 2024 the project is in the process of migrating from a MongoDB (NoSQL) database to a SQL Server (SQL) database. MongoDB collections will gradually be replaced with SQL Server tables until MongoDB can be completely removed.
The SQL Server database will be spun up in Docker along with all the other services (see the docker-compose step in Setup in the main README).
Below are some example systems you can use to connect to the database locally if required:
- SSMS (Windows only) - dedicated SQL Server tool from Microsoft
- DataGrip (Windows, Mac, and Linux) - generic database tool from JetBrains
- Azure Data Studio (Windows, Mac, and Linux) - a lightweight database tool from Microsoft
Use the SQL_DB...
values in the common package .env.sample to connect.
You can update the mock seeding by navigating to the utils/sql-db-seeder/src
and making changes.
To run the seeder, see the seeding data command below.
In order to generate data which is in line with the data in MongoDB, the SQL db seeder needs to query data inserted by the mock data loader. Additionally, we need to seed tfm facilities for every facility id used by fee records inserted by the SQL db seeder (otherwise generate keying data will fail). This results in three things which are important to remember:
- The
mock-data-loader
script must be run before the SQL seeder - The
create-tfm-keying-sheet-facilities
script must be run after the SQL seeder. - The
utils/sql-db-seeder
.env
file must include the connection strings required to initialise the MongoDbClient and the SqlDbDataSource (see .env.sample)
The database is shared across the entire project, so commands are defined in the common package where the shared DB configuration lives.
Configure SQL Server settings with environment variables on Linux.
When running commands you can either navigate to the common package, e.g.
cd libs/common
npm run db:migrate
or run commands from the root directory with the workspaces flag, e.g.
npm run db:migrate -w libs/common
Because the commands are run from the common package, the common package needs its own set of environment variables to facilitate the connection.
In the common package copy the .env.sample to a new .env
file in the same directory. For the local DB connection there shouldn't be any additional sensitive values that need to be obtained from elsewhere. Note: most values will be the same as those in the root .env
file and used to spin up the Docker container, with the exception being SQL_DB_HOST
which points at localhost
as we are running from outside the docker-compose environment.
npm run db:generate-migration --name=<description_of_change>
# e.g. npm run db:generate-migration --name=AddUserTable
This command will connect to the DB and compare any defined entities in the entity directory to the schema of the actual DB. It will then automatically generate a file in the migrations directory that would resolve the differences in the database when run.
The resulting file will be prefixed with a unix timestamp of the current time so that files are listed in order of creation. e.g. for the example command above the following could be created:
1706102208471-AddUserTable.ts
This time stamp and order is important because it determines the order in which the migrations are run (see Run migrations below).
In the new file there will be two functions:
up
: how to apply the new changesdown
: how to revert the changes
npm run db:migrate
TypeORM automatically tracks which migrations have already been run in a migrations
table in the database.
migrations
table and run any ordered after that one. For this reason we must take care to ensure that any new migrations are added in the correct order when merging git branches.
npm run db:migrate:down
Note: this only reverts the latest executed migration. If you need to revert multiple migrations you must call this command multiple times.
npm run db:reset
Use to start the SQL Server database from scratch. This will restart the docker container, delete and recreate the database, recreate the database user which is used inside the other services and run all the migrations. In effect, this resets the database to a clean state.
npm run db:remove-ledger
Use to remove the ledger tables if you have them enabled. This command will restart the SQL container and recreate the database user which is used inside the other services.
npm run db:seed
Use to seed data for utilisation reports into the SQL database.
Though the DB configuration is contained within the common package, it is up to each package that needs access to initialise a connection to the DB. This is done by adding the following to a file where the app is first initialised:
const { SqlDbDataSource } = require('@ukef/dtfs2-common/sql-db-connection');
SqlDbDataSource.initialize()
.then(() => console.info('✅ Successfully initialised connection to SQL database'))
.catch((error) => console.error('❌ Failed to initialise connection to SQL database:', error));
e.g. in the dtfs-central-api project this has been added to generateApp.js.
The package will then need to be given access to the following environment variables:
SQL_DB_HOST
SQL_DB_PORT
SQL_DB_USERNAME
SQL_DB_PASSWORD
SQL_DB_NAME
SQL_DB_LOGGING_ENABLED
Note: in contrast to other common functionality which is imported from '@ukef/dtfs2-common'
, the SqlDbDataSource
is imported from a separate '@ukef/dtfs2-common/sql-db-connection'
sub-directory. This means that only those packages that need to connect to the DB and import from this sub-directory will need to be provided with access to the required environment variables.