Queries
Cot provides a Query interface that allows you to write queries
to the database. In this guide, we’ll cover the basics of writing queries after you’ve setup your
database and models. For a complete reference, see the Query docs.
For the rest of this guide, we’ll use the following models which show a simple e-commerce application.
use ;
use ;
use ;
pub
pub
pub
Creating an object
To create a new model instance, cot provides the insert method.
In the example below, we create a new Customer instance and save it to the database.
use ;
use ;
async
Keep in mind that the insert method will return a UniqueViolation error if a record with the same primary key already exists.
The example below shows an attempt to insert a new Customer instance with the same primary key as an existing one.
use ;
use ;
async
Creating multiple objects
If you need to create multiple objects, cot provides the bulk_insert method for this purpose.
It is recommended to prefer bulk_insert for multiple insertions as it performs the operations in a single database query which is much more efficient than performing multiple individual insert or save calls.
The example below shows how to create multiple Customer instances.
use ;
use ;
async
Keep in mind that bulk_insert takes a mutable slice of models, because it needs to update the primary keys of the inserted models with the values generated by the database.
Similarly, there is also bulk_insert_or_update method, which works like bulk_insert, but updates the existing rows if they conflict with the new ones.
Updating an object
Cot provides the update method to update an existing model instance.
The example below shows how to update the full_name field of a Customer instance.
= ;
?;
Creating or Updating an object
Cot provides the save method to create a new model instance if it doesn’t exist, or update it if it does.
In the example below, we create a Customer instance if it doesnt exist and then update it’s verified status.
use ;
use ;
async
Saving ForeignKey fields
Saving a foreign key field is similar to saving a regular field, and Cot provides two variants for foreign key fields: ForeignKey::Model and ForeignKey::PrimaryKey.
The key thing to keep in mind when saving any foreign key field is that the referenced model instance must already exist in the database before the relation can be saved.
ForeignKey::Model
This is the most common variant, which lets you associate a model instance directly as a foreign key field. The example below shows how to first persist a Customer and a Product instance, then reference them as foreign key fields on an Order.
use ;
use ;
async
ForeignKey::PrimaryKey
This variant lets you set a foreign key field using only the primary key of the referenced model, without needing to have the model instance in hand. This is useful when you already know the ID of the related record.
The example below saves an Order referencing existing Customer and Product records by their primary keys directly.
use ;
async
Keep in mind that if the provided primary key does not correspond to an existing record in the database, the save will fail.
Retrieving objects
To retrieve objects from the database, cot provides the query! macro which offers a convenient and declarative way to write queries.
The macro takes two arguments: the model to query as the first argument, and a filter condition as the second, written using a natural expression syntax where fields are prefixed with $. The example below shows how to retrieve a Customer instance with the primary key of 5.
use ;
async
The query! macro returns a Query object, on which you can call terminal methods (such as get which returns the first matching result, and all which returns all matching results) to retrieve the final results.
Using the Query struct
The query! macro is syntactic sugar for manually constructing a Query with Expr expressions. The Query object can be accessed directly by calling the objects method on the model, and filtered using the filter method.
You may prefer this approach when you need more control over how expressions are constructed. The example below is equivalent to the one above:
use ;
use ;
async
The filter method takes a filter expression. In the example above, the expression Expr::eq(Expr::field("id"), Expr::value("5")) is evaluated as id = 5.
Retrieving all objects
One way to retrieve all objects of a model is to call the all method after filtering the query results.
use ;
use ;
async
The example above retrieves all customers with a primary key greater than 5. This returns a list of Customer instances.
Chaining filters
The filter method returns a new Query instance which makes it convenient to chain multiple filters.
use ;
use ;
async
The example above shows how to retrieve all customers with a primary key greater than 5 and whose full name is Jon Doe.
Note: Although this example works, the idiomatic way to do this is to use the
Expr::andexpression instead.
Similarly, the query macro returns a new Query instance which can be used to chain multiple filters.
Removing an object
The delete method can be used to remove an object from the database. The example below shows how to remove a Customer instance with the primary key of 5.
use ;
async
Other Query methods
The methods listed on this page are the most commonly used query methods. For a complete comprehensive list of supported query methods, see the Query docs.