From 746828d698bfa21d7177c06e4863ce69452dda10 Mon Sep 17 00:00:00 2001 From: Marcelo Soares Date: Mon, 18 May 2026 22:29:52 -0300 Subject: [PATCH] feat: Move the `column` keyword to override column names out of experimental --- docs/06-concepts/02-models/01-models.md | 2 +- docs/06-concepts/06-database/02-models.md | 95 ++++++++++++++++++++ docs/06-concepts/22-experimental.md | 105 ---------------------- 3 files changed, 96 insertions(+), 106 deletions(-) diff --git a/docs/06-concepts/02-models/01-models.md b/docs/06-concepts/02-models/01-models.md index 67609f43..7b30b0e2 100644 --- a/docs/06-concepts/02-models/01-models.md +++ b/docs/06-concepts/02-models/01-models.md @@ -106,7 +106,7 @@ This is particularly helpful when: - Integrating with third-party services like MongoDB (e.g., mapping `id` to `_id`) :::info -The `jsonKey` property affects JSON serialization and deserialization. It does not affect the database column name. To customize the database column name, use the `column` property instead. This is an experimental feature; see the [Experimental documentation](experimental#column-name-override) under *Column name override* for details. +The `jsonKey` property affects JSON serialization and deserialization. It does not affect the database column name. To customize the database column name, use the [`column` property](database/models#column-name-override) instead. ::: ### Immutable classes diff --git a/docs/06-concepts/06-database/02-models.md b/docs/06-concepts/06-database/02-models.md index 4283cf84..199d6999 100644 --- a/docs/06-concepts/06-database/02-models.md +++ b/docs/06-concepts/06-database/02-models.md @@ -146,3 +146,98 @@ fields: ``` When using `defaultModel=random`, the UUID will be generated when the object is created. Since an id is always assigned the `id` field can be non-nullable. + +## Column name override + +By default, the column name in the database is the same as the name of the field in the model. However, you can override this to use a different name by using the `column` keyword. For example, if you have a model property named `userName` you might want to store it in the database as `user_name`. + +To override the column name, use the `column` keyword on the field definition: + +```yaml +class: User +table: users +fields: + userName: String, column=user_name +``` + +:::info +When adding a column name override to an existing model, the next migration will contain a column rename operation to rename the column in the database. +::: + +Restrictions: + +- The `id` field cannot have a column name override. +- The column name must be unique within the model. +- The `column` keyword is only allowed on the [foreign key field](relations/one-to-one#with-an-id-field) of a relation. + +### Relations + +You can use the `column` keyword to override the name of the foreign key field in a relation. + +```yaml +# Employee +class: Employee +table: employee +fields: + name: String + departmentId: int, relation(name=department_employees, parent=department), column=fk_employee_department_id + +# Department +class: Department +table: department +fields: + name: String + employees: List?, relation(name=department_employees) +``` + +Overriding the column name is also supported when the field is used in an index. Note that the index uses the name of the field, not the column name. + +```yaml +# Contractor +class: Contractor +table: contractor +fields: + name: String + serviceIdField: int?, column=fk_contractor_service_id + service: Service?, relation(field=serviceIdField) +indexes: + contractor_service_unique_idx: + fields: serviceIdField + unique: true + +# Service +class: Service +table: service +fields: + name: String + description: String? +``` + +### Inheritance + +Besides column override being a database-level feature, it is allowed to be set on non-table models to support [inheritance](../models/inheritance-and-polymorphism). If a base class has a column name override, all child classes that implement a table will inherit the column name override. This is especially useful when you have multiple database tables that share similar column names. + +```yaml +# Entity +class: Entity +fields: + name: String + createdAt: DateTime, default=now, column=created_at + updatedAt: DateTime, default=now, column=updated_at + +# Employee +class: Employee +extends: Entity +table: employee +fields: + departmentId: int, relation(name=department_employees, parent=department), column=fk_employee_department_id + +# Department +class: Department +extends: Entity +table: department +fields: + employees: List?, relation(name=department_employees) +``` + +In the above example, the `Employee` and `Department` classes will receive the `createdAt` and `updatedAt` fields from the `Entity` class with the columns overridden to `created_at` and `updated_at`, respectively. diff --git a/docs/06-concepts/22-experimental.md b/docs/06-concepts/22-experimental.md index 9f053f2e..0aa97d5d 100644 --- a/docs/06-concepts/22-experimental.md +++ b/docs/06-concepts/22-experimental.md @@ -33,111 +33,6 @@ The current options you can pass are: | **Feature** | Description | | :----------------- | :------------------------------------------------------------- | | **all** | Enables all available experimental features. | -| **columnOverride** | Allows overriding the column name for a field in the database. | - -## Column name override - -Serverpod allows you to specify the column name for a field in the database overriding the default use of the model property name as the column name. -This can be useful when the column names in the database are not following the same naming convention as the model properties. - -### Usage - -To override the column name, use the `column` keyword in the `fields` configuration of your [model](database/models) file to specify the column name in the database. - -```yaml -class: User -table: users -fields: - userName: String, column=user_name -``` - -### Restrictions - -- **ID Field**: The `id` field cannot have a column name override. -- **Unique**: The column name must be unique within the model. -- **Relations**: The `column` keyword is only allowed on the [foreign key field](database/relations/one-to-one#with-an-id-field) of a relation. - -### Relations - -You can use the `column` keyword to override the name of the foreign key field in a relation. - -```yaml -# Employee -class: Employee -table: employee -fields: - name: String - departmentId: int, relation(name=department_employees, parent=department), column=fk_employee_department_id - -# Department -class: Department -table: department -fields: - name: String - employees: List?, relation(name=department_employees) -``` - -This is also supported when the field is used in an index. - -```yaml -# Contractor -class: Contractor -table: contractor -fields: - name: String - serviceIdField: int?, column=fk_contractor_service_id - service: Service?, relation(field=serviceIdField) -indexes: - contractor_service_unique_idx: - fields: serviceIdField - unique: true - -# Service -class: Service -table: service -fields: - name: String - description: String? -``` - -### Inheritance - -The column name override is also supported when using [inheritance](models/inheritance-and-polymorphism#inheritance) and will be applied to all child classes. This is especially useful when you have multiple database tables that share similar column names. This allows you to define a parent class as a regular [model](../get-started/models-and-data) and specify additional fields in the child classes defined as [table models](database/models). - -```yaml -# Entity -class: Entity -fields: - name: String - createdAt: DateTime, default=now, column=created_at - updatedAt: DateTime, default=now, column=updated_at - -# Employee -class: Employee -extends: Entity -table: employee -fields: - departmentId: int, relation(name=department_employees, parent=department), column=fk_employee_department_id - -# Department -class: Department -extends: Entity -table: department -fields: - employees: List?, relation(name=department_employees) - -# Contractor -class: Contractor -extends: Entity -table: contractor -fields: - serviceIdField: int?, column=fk_contractor_service_id - service: Service?, relation(field=serviceIdField) -indexes: - contractor_service_unique_idx: - fields: serviceIdField - unique: true -``` ## Exception monitoring