3.4. Data Models
In this chapter, you'll learn what a data model is and how to create a data model.
What is a Data Model?#
A data model represents a table in the database. You create data models using Medusa's data modeling language (DML). It simplifies defining a table's columns, relations, and indexes with straightforward methods and configurations.
You create a data model in a module. The module's service provides the methods to store and manage those data models. Then, you can resolve the module's service in other customizations, such as a workflow, to manage the data models' records.
How to Create a Data Model#
In a module, you can create a data model in a TypeScript or JavaScript file under the module's models
directory.
So, for example, assuming you have a Blog Module at src/modules/blog
, you can create a Post
data model by creating the src/modules/blog/models/post.ts
file with the following content:
You define the data model using the define
method of the DML. It accepts two parameters:
- The first one is the name of the data model's table in the database. Use snake-case names.
- The second is an object, which is the data model's schema. The schema's properties are defined using the
model
's methods, such astext
andid
.- Data models automatically have the date properties
created_at
,updated_at
, anddeleted_at
, so you don't need to add them manually.
- Data models automatically have the date properties
The code snippet above defines a Post
data model with id
and title
properties.
Generate Migrations#
After you create a data model in a module, then register that module in your Medusa configurations, you must generate a migration to create the data model's table in the database.
A migration is a TypeScript or JavaScript file that defines database changes made by a module. Migrations are useful when you re-use a module or you're working in a team, so that when one member of a team makes a database change, everyone else can reflect it on their side by running the migrations.
For example, to generate a migration for the Blog Module, run the following command in your Medusa application's directory:
The db:generate
command of the Medusa CLI accepts one or more module names to generate the migration for. It will create a migration file for the Blog Module in the directory src/modules/blog/migrations
similar to the following:
1import { Migration } from "@mikro-orm/migrations"2 3export class Migration20241121103722 extends Migration {4 5 async up(): Promise<void> {6 this.addSql("create table if not exists \"post\" (\"id\" text not null, \"title\" text not null, \"created_at\" timestamptz not null default now(), \"updated_at\" timestamptz not null default now(), \"deleted_at\" timestamptz null, constraint \"post_pkey\" primary key (\"id\"));")7 }8 9 async down(): Promise<void> {10 this.addSql("drop table if exists \"post\" cascade;")11 }12 13}
In the migration class, the up
method creates the table post
and defines its columns using PostgreSQL syntax. The down
method drops the table.
Run Migrations#
To reflect the changes in the generated migration file on the database, run the db:migrate
command:
This creates the post
table in the database.
Migrations on Data Model Changes#
Whenever you make a change to a data model, you must generate and run the migrations.
For example, if you add a new column to the Post
data model, you must generate a new migration and run it.
Manage Data Models#
Your module's service should extend the service factory, which generates data-management methods for your module's data models.
For example, the Blog Module's service would have methods like retrievePost
and createPosts
.
Refer to the Service Factory chapter to learn more about how to extend the service factory and manage data models, and refer to the Service Factory Reference for the full list of generated methods and how to use them.