Data Models
In this chapter, you'll learn what data models are and how to create a data model in a module.
What is a Data Model?#
A data model represents a table in the database. You create data models in a module, and they hold the data the module manages.
You create a data model with the Data Model Language (DML), which is the dml package of MedusaGo. It's an alternative to writing SQL tables by hand: you define the properties and relationships of the data model in Go, and MedusaGo derives the table, its columns, indexes, and foreign keys from the definition. Then you generate migrations that create the tables in the database.
The module's service gets methods to manage the data model's records from the service factory, without you writing them.
How to Create a Data Model#
In a module, create the file models.go that defines the module's data models. For example, the Blog Module of the Modules chapter has a Post data model:
var Post = dml.Define("post", dml.Schema{
{Name: "id", Property: dml.Id(dml.IdOptions{Prefix: "post"}).PrimaryKey()},
{Name: "title", Property: dml.Text().Searchable()},
{Name: "slug", Property: dml.Text().Unique()},
{Name: "content", Property: dml.Text().Nullable()},
{Name: "status", Property: dml.Enum("draft", "published", "archived").Default("draft")},
{Name: "views", Property: dml.Number().Default(0)},
{Name: "published_at", Property: dml.DateTime().Nullable()},
{Name: "author_id", Property: dml.Text().Nullable()},
{Name: "metadata", Property: dml.JSON().Nullable()},
{Name: "comments", Property: dml.HasMany("Comment", dml.RelationshipOptions{MappedBy: "post"})},
{Name: "tags", Property: dml.ManyToMany("Tag", dml.RelationshipOptions{MappedBy: "posts"})},
}).
WithIndexes([]dml.Index{{On: []string{"status", "published_at"}}}).
WithCascades(dml.Cascades{Delete: []string{"comments"}})
The dml package is imported like this:
A data model is a variable that holds the result of dml.Define. The function takes:
- The name of the data model's table,
"post". MedusaGo derives the name of the data model from it:Post. You use that name in the service, for example inInternal("Post"), and in relationships. - The schema, a
dml.Schema. It's a list of the properties, in the order of the table's columns. Each entry has aName, which is the name of the column or the relationship, and aProperty, which describes it.
The schema above has:
- An
idproperty, which is the primary key. ItsPrefixmakes the generated IDs look likepost_01J.... - Text, enum, number, date-time, and JSON properties, with modifiers such as
Unique,Nullable, andDefault. Learn more in the Properties chapter. - The relationships
commentsandtags. Learn more in the Relationships chapter.
The WithIndexes and WithCascades methods add an index and a deletion cascade to the data model.
You pass the data models to the module's definition, in its Models field, as in the Models variable of the file:
// Models lists the data models of the module.
var Models = []*dml.Entity{Post, Comment, Tag}
created_at, updated_at, and deleted_at properties, and MedusaGo sets them for you. You can't define a property with one of these names: dml.Define panics when you do. created_at and updated_at are set when a record is created and updated, and deleted_at is set when you soft-delete it.Generate Migrations#
After you create a data model, you generate a migration for it. A migration holds the SQL statements that create or change the data model's table.
To generate the migration of a module, run the following command in your application's directory, where blog is the key of the module:
The command compares the module's data models with the snapshot of its previous migration, and writes a migration with the difference. For a new module, that's the creation of its tables.
Run Migrations#
To apply the migration and create the tables, run:
Migrations on Data Model Changes#
Each time you change a data model, for example when you add a property, generate a new migration and run it. The command writes a new migration with the statements that change the existing table, so you don't lose the data in it.
Learn more about migrations, including how to write them manually, in the Migrations chapter.
Manage Data Models#
To manage the records of a data model, use the methods that the service factory generates for your module's service. For example, createPosts and listPosts create and list the records of the Post data model.
Learn more in the Service Factory chapter.
Chapters on Data Models#
- Properties: the types of properties and their modifiers.
- Relationships: one-to-one, one-to-many, and many-to-many relationships, and cascades.
- Indexes: database indexes and check constraints.
- Migrations: generate, write, run, and roll back migrations.