Update schema.md field constraints list (#1069)

A reference to .sql() was added to the Field Constraint list so that
anyone who is looking for any other options knows there is the
possibility to use SQLKit.
This commit is contained in:
Francisco Bretal 2025-03-17 09:51:59 +01:00 committed by GitHub
parent 810f673b86
commit 2b0abd625f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 24 additions and 23 deletions

View File

@ -11,15 +11,15 @@ try await database.schema("planets")
.create() .create()
``` ```
To create a `SchemaBuilder`, use the `schema` method on database. Pass in the name of the table or collection you want to affect. If you are editing the schema for a model, make sure this name matches the model's [`schema`](model.md#schema). To create a `SchemaBuilder`, use the `schema` method on database. Pass in the name of the table or collection you want to affect. If you are editing the schema for a model, make sure this name matches the model's [`schema`](model.md#schema).
## Actions ## Actions
The schema API supports creating, updating, and deleting schemas. Each action supports a subset of the API's available methods. The schema API supports creating, updating, and deleting schemas. Each action supports a subset of the API's available methods.
### Create ### Create
Calling `create()` creates a new table or collection in the database. All methods for defining new fields and constraints are supported. Methods for updates or deletes are ignored. Calling `create()` creates a new table or collection in the database. All methods for defining new fields and constraints are supported. Methods for updates or deletes are ignored.
```swift ```swift
// An example schema creation. // An example schema creation.
@ -29,7 +29,7 @@ try await database.schema("planets")
.create() .create()
``` ```
If a table or collection with the chosen name already exists, an error will be thrown. To ignore this, use `.ignoreExisting()`. If a table or collection with the chosen name already exists, an error will be thrown. To ignore this, use `.ignoreExisting()`.
### Update ### Update
@ -54,14 +54,14 @@ database.schema("planets").delete()
## Field ## Field
Fields can be added when creating or updating a schema. Fields can be added when creating or updating a schema.
```swift ```swift
// Adds a new field // Adds a new field
.field("name", .string, .required) .field("name", .string, .required)
``` ```
The first parameter is the name of the field. This should match the key used on the associated model property. The second parameter is the field's [data type](#data-type). Finally, zero or more [constraints](#field-constraint) can be added. The first parameter is the name of the field. This should match the key used on the associated model property. The second parameter is the field's [data type](#data-type). Finally, zero or more [constraints](#field-constraint) can be added.
### Data Type ### Data Type
@ -86,13 +86,14 @@ Supported field data types are listed below.
### Field Constraint ### Field Constraint
Supported field constraints are listed below. Supported field constraints are listed below.
|FieldConstraint|Description| |FieldConstraint|Description|
|-|-| |-|-|
|`.required`|Disallows `nil` values.| |`.required`|Disallows `nil` values.|
|`.references`|Requires that this field's value match a value in the referenced schema. See [foreign key](#foreign-key)| |`.references`|Requires that this field's value match a value in the referenced schema. See [foreign key](#foreign-key).|
|`.identifier`|Denotes the primary key. See [identifier](#identifier)| |`.identifier`|Denotes the primary key. See [identifier](#identifier).|
|`.sql(SQLColumnConstraintAlgorithm)`|Defines any constraint that is not supported (e.g. `default`). See [SQL](#sql) and [SQLColumnConstraintAlgorithm](https://api.vapor.codes/sqlkit/documentation/sqlkit/sqlcolumnconstraintalgorithm/).|
### Identifier ### Identifier
@ -103,18 +104,18 @@ If your model uses a standard `@ID` property, you can use the `id()` helper to c
.id() .id()
``` ```
For custom identifier types, you will need to specify the field manually. For custom identifier types, you will need to specify the field manually.
```swift ```swift
// Adds field for custom identifier. // Adds field for custom identifier.
.field("id", .int, .identifier(auto: true)) .field("id", .int, .identifier(auto: true))
``` ```
The `identifier` constraint may be used on a single field and denotes the primary key. The `auto` flag determines whether or not the database should generate this value automatically. The `identifier` constraint may be used on a single field and denotes the primary key. The `auto` flag determines whether or not the database should generate this value automatically.
### Update Field ### Update Field
You can update a field's data type using `updateField`. You can update a field's data type using `updateField`.
```swift ```swift
// Updates the field to `double` data type. // Updates the field to `double` data type.
@ -138,7 +139,7 @@ Constraints can be added when creating or updating a schema. Unlike [field const
### Unique ### Unique
A unique constraint requires that there are no duplicate values in one or more fields. A unique constraint requires that there are no duplicate values in one or more fields.
```swift ```swift
// Disallow duplicate email addresses. // Disallow duplicate email addresses.
@ -152,7 +153,7 @@ If multiple field are constrained, the specific combination of each field's valu
.unique(on: "first_name", "last_name") .unique(on: "first_name", "last_name")
``` ```
To delete a unique constraint, use `deleteUnique`. To delete a unique constraint, use `deleteUnique`.
```swift ```swift
// Removes duplicate email constraint. // Removes duplicate email constraint.
@ -168,7 +169,7 @@ Fluent will generate unique constraint names by default. However, you may want t
.unique(on: "email", name: "no_duplicate_emails") .unique(on: "email", name: "no_duplicate_emails")
``` ```
To delete a named constraint, you must use `deleteConstraint(name:)`. To delete a named constraint, you must use `deleteConstraint(name:)`.
```swift ```swift
// Removes duplicate email constraint. // Removes duplicate email constraint.
@ -177,7 +178,7 @@ To delete a named constraint, you must use `deleteConstraint(name:)`.
## Foreign Key ## Foreign Key
Foreign key constraints require that a field's value match ones of the values in the referenced field. This is useful for preventing invalid data from being saved. Foreign key constraints can be added as either a field or top-level constraint. Foreign key constraints require that a field's value match ones of the values in the referenced field. This is useful for preventing invalid data from being saved. Foreign key constraints can be added as either a field or top-level constraint.
To add a foreign key constraint to a field, use `.references`. To add a foreign key constraint to a field, use `.references`.
@ -195,7 +196,7 @@ This same constraint could be added as a top-level constraint using `foreignKey`
.foreignKey("star_id", references: "stars", "id") .foreignKey("star_id", references: "stars", "id")
``` ```
Unlike field constraints, top-level constraints can be added in a schema update. They can also be [named](#constraint-name). Unlike field constraints, top-level constraints can be added in a schema update. They can also be [named](#constraint-name).
Foreign key constraints support optional `onDelete` and `onUpdate` actions. Foreign key constraints support optional `onDelete` and `onUpdate` actions.
@ -215,7 +216,7 @@ Below is an example using foreign key actions.
``` ```
!!! warning !!! warning
Foreign key actions happen solely in the database, bypassing Fluent. Foreign key actions happen solely in the database, bypassing Fluent.
This means things like model middleware and soft-delete may not work correctly. This means things like model middleware and soft-delete may not work correctly.
## SQL ## SQL
@ -235,7 +236,7 @@ or even a default value for a timestamp:
## Dictionary ## Dictionary
The dictionary data type is capable of storing nested dictionary values. This includes structs that conform to `Codable` and Swift dictionaries with a `Codable` value. The dictionary data type is capable of storing nested dictionary values. This includes structs that conform to `Codable` and Swift dictionaries with a `Codable` value.
!!! note !!! note
Fluent's SQL database drivers store nested dictionaries in JSON columns. Fluent's SQL database drivers store nested dictionaries in JSON columns.
@ -262,7 +263,7 @@ This field can be stored using the `.dictionary(of:)` data type.
.field("pet", .dictionary, .required) .field("pet", .dictionary, .required)
``` ```
Since `Codable` types are heterogenous dictionaries, we do not specify the `of` parameter. Since `Codable` types are heterogenous dictionaries, we do not specify the `of` parameter.
If the dictionary values were homogenous, for example `[String: Int]`, the `of` parameter would specify the value type. If the dictionary values were homogenous, for example `[String: Int]`, the `of` parameter would specify the value type.
@ -270,7 +271,7 @@ If the dictionary values were homogenous, for example `[String: Int]`, the `of`
.field("numbers", .dictionary(of: .int), .required) .field("numbers", .dictionary(of: .int), .required)
``` ```
Dictionary keys must always be strings. Dictionary keys must always be strings.
## Array ## Array
@ -289,7 +290,7 @@ This field can be stored using the `.array(of:)` data type.
.field("tags", .array(of: .string), .required) .field("tags", .array(of: .string), .required)
``` ```
Since the array is homogenous, we specify the `of` parameter. Since the array is homogenous, we specify the `of` parameter.
Codable Swift `Array`s will always have a homogenous value type. Custom `Codable` types that serialize heterogenous values to unkeyed containers are the exception and should use the `.array` data type. Codable Swift `Array`s will always have a homogenous value type. Custom `Codable` types that serialize heterogenous values to unkeyed containers are the exception and should use the `.array` data type.
@ -391,7 +392,7 @@ struct UserNameMigration: AsyncMigration {
try await User.query(on: database) try await User.query(on: database)
.set(["first_name": .sql(embed: "name")) .set(["first_name": .sql(embed: "name"))
.run() .run()
try await database.schema("users") try await database.schema("users")
.deleteField("name") .deleteField("name")
.update() .update()