Skip to main content
Version: 3.x

Model

The model construct is the core of ZModel. It defines the structure of your data and relations. A model represents a domain entity and is backed by a database table.

Defining models​

A typical model looks like this:

model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
name String
}

The simplest models are just a collection of fields. A model must be uniquely identifiable by some of its fields. In most cases, you'll have a field marked with the @id attribute (more about attributes later).

model User {
id Int @id
}

If your model needs a composite ID, you can use the @@id model-level attribute to specify it:

model City {
country String
name String
@@id([country, name])
}

If no @id or @@id is specified, the ORM will resort to using a field (or fields) marked with the @unique or @@unique attribute as the identifier.

model User {
email String @unique
}

model City {
country String
name String
@@unique([country, name])
}

Model fields​

Each model field must at least have a name and a type. A field can be typed in one of the following ways:

  1. Built-in types, including:

    • String
    • Boolean
    • Int
    • BigInt
    • Float
    • Decimal
    • DateTime
    • Json
    • Bytes
    • Unsupported

    The Unsupported type is for defining fields of types not supported by the ORM. It lets the migration engine know how to create the field in the database.

    // from Prisma docs
    model Star {
    id Int @id
    position Unsupported("circle")? @default(dbgenerated("'<(10,4),11>'::circle"))
    }
  2. Enum

    We'll talk about enums later.

    enum Role {
    USER
    ADMIN
    }

    model User {
    id Int @id
    role Role
    }
  3. Model

    It'll then form a relation. We'll cover that topic later.

    model Post {
    id Int @id
    author User @relation(fields: [authorId], references: [id])
    authorId Int
    }
  4. Custom type

    ZenStack allows you to define custom types in the schema and use them to type JSON fields. This is covered in more detail in the Custom Type section.

    type Address {
    street String
    city String
    country String
    zip Int
    }

    model User {
    id Int @id
    address Address @json
    }

A field can be set as optional by adding the ? suffix to its type, or list by adding the [] suffix. However, a field cannot be both optional and a list at the same time.

model User {
id Int @id
name String?
tags String[]
}

Default values​

A default value can be specified for a field with the @default attribute. The value can be a literal, an enum value, or a supported function call, including:

model User {
id Int @id @default(autoincrement())
role Role @default(USER)
createdAt DateTime @default(now())
}

Custom ID formats​

Available since v3.1.0

Prefixing and suffixing entity IDs is becoming more common in database design, usually by including the model name in the generated ID. To support this pattern, functions that generate String IDs (cuid(), uuid(), ulid(), nanoid()) takes an optional format argument to allow passing in a pattern that controls the output format. %s in the pattern will be replaced by the generated id. For example:

model User {
// generate a UUID v4 with "user_" prefix
id String @id @default(uuid(4, "user_%s"))
}

Native type mapping​

Besides giving a field a type, you can also specify the native database type to use with the @db. series of attributes.

model User {
...
name String @db.VarChar(64)
}

These attributes control what data type is used when the migration engine maps the schema to DDL. You can find a complete list of native type attributes in the ZModel Language Reference.

Name mapping​

Quite often, you want to use a different naming scheme for your models and fields than the database. You can achieve that with the @map and @@map attribute. The ORM respects the mapping when generating queries, and the migration engine uses it to generate the DDL.

model User {
id Int @id @map('_id')
@@map('users')
}
Comments
Feel free to ask questions, give feedback, or report issues.

Don't Spam


You can edit/delete your comments by going directly to the discussion, clicking on the 'comments' link below