Generated Columns
To use this feature you would need to have drizzle-orm@0.32.0
or higher and drizzle-kit@0.23.0
or higher
Generated columns in SQL are a feature that allows you to create columns in a table whose values are automatically computed based on expressions involving other columns within the same table. This can help ensure data consistency, simplify database design, and improve query performance.
There are two types of generated columns:
-
Virtual (or non-persistent) Generated Columns: These columns are computed dynamically whenever they are queried. They do not occupy storage space in the database.
-
Stored (or persistent) Generated Columns: These columns are computed when a row is inserted or updated and their values are stored in the database. This allows them to be indexed and can improve query performance since the values do not need to be recomputed for each query.
Generated columns can be especially useful for:
- Deriving new data from existing columns
- Automating calculations to avoid manual updates
- Enforcing data integrity and consistency
- Simplifying application logic by keeping complex calculations within the database schema
The implementation and usage of generated columns can vary significantly across different SQL databases. PostgreSQL, MySQL, and SQLite each have unique features, capabilities, and limitations when it comes to generated columns. In this section, we will explore these differences in detail to help you understand how to best utilize generated columns in each database system.
Database side
Types: STORED
only
How It Works
- Automatically computes values based on other columns during insert or update.
Capabilities
- Simplifies data access by precomputing complex expressions.
- Enhances query performance with index support on generated columns.
Limitations
- Cannot specify default values.
- Expressions cannot reference other generated columns or include subqueries.
- Schema changes required to modify generated column expressions.
- Cannot directly use in primary keys, foreign keys, or unique constraints
For more info, please check PostgreSQL docs
Drizzle side
In Drizzle you can specify .generatedAlwaysAs()
function on any column type and add a supported sql query,
that will generate this column data do you
Features
This function can accept generated expression in 3 ways:
string
sql
tag - if you want drizzle to escape some values for you
callback
- if you need to reference columns from a table
Example generated columns with full-text search
Database side
Types: STORED
, VIRTUAL
How It Works
- Defined with an expression in the table schema.
- Virtual columns are computed during read operations.
- Stored columns are computed during write operations and stored.
Capabilities
- Used in SELECT, INSERT, UPDATE, and DELETE statements.
- Can be indexed, both virtual and stored.
- Can specify NOT NULL and other constraints.
Limitations
- Cannot directly insert or update values in a generated column
For more info, please check MySQL Alter Generated docs and MySQL create generated docs
Drizzle side
Features
string
sql
tag - if you want drizzle to escape some values for you
callback
- if you need to reference columns from a table
Limitations
Drizzle Kit will also have limitations for push
command:
- You can’t change the generated constraint expression and type using
push
. Drizzle-kit will ignore this change. To make it work, you would need todrop the column
,push
, and thenadd a column with a new expression
. This was done due to the complex mapping from the database side, where the schema expression will be modified on the database side and, on introspection, we will get a different string. We can’t be sure if you changed this expression or if it was changed and formatted by the database. As long as these are generated columns andpush
is mostly used for prototyping on a local database, it should be fast todrop
andcreate
generated columns. Since these columns aregenerated
, all the data will be restored generate
should have no limitations
Database side
Types: STORED
, VIRTUAL
How It Works
- Defined with an expression in the table schema.
- Virtual columns are computed during read operations.
- Stored columns are computed during write operations and stored.
Capabilities
- Used in SELECT, INSERT, UPDATE, and DELETE statements.
- Can be indexed, both virtual and stored.
- Can specify NOT NULL and other constraints.
Limitations
- Cannot directly insert or update values in a generated column
For more info, please check SQLite docs
Drizzle side
Features
string
sql
tag - if you want drizzle to escape some values for you
callback
- if you need to reference columns from a table
Limitations
Drizzle Kit will also have limitations for push
and generate
command:
- You can’t change the generated constraint expression with the stored type in an existing table. You would need to delete this table and create it again. This is due to SQLite limitations for such actions. We will handle this case in future releases (it will involve the creation of a new table with data migration).
- You can’t add a
stored
generated expression to an existing column for the same reason as above. However, you can add avirtual
expression to an existing column. - You can’t change a
stored
generated expression in an existing column for the same reason as above. However, you can change avirtual
expression. - You can’t change the generated constraint type from
virtual
tostored
for the same reason as above. However, you can change fromstored
tovirtual
.