Define read-only database views with custom SQL for aggregations, joins, and complex queries.
Database views are virtual tables defined by SQL queries. They provide a way to encapsulate complex queries, aggregate data, and expose a simplified interface for reading data. Views in Prax are read-only and generate type-safe Rust code for querying.
Define a view with the view keyword,
fields that match your SQL output, and a @@sql()
attribute containing the query.
Views can be as simple as filtering or joining data. Use @map()
to map field names to SQL column aliases.
For expensive queries that don't need real-time data, use materialized views. They store the query results and can be refreshed periodically. Supported on PostgreSQL.
Note: Materialized views need to be refreshed manually or on a schedule.
Use REFRESH MATERIALIZED VIEW view_name in PostgreSQL
or configure automatic refresh with @@refreshInterval.
Here's a complete example showing models and a view that aggregates their data:
Views are queried using the same type-safe API as models. All read operations (find_many, find_unique, find_first, count, aggregate) are available.
Different databases offer unique view capabilities. Prax supports database-specific SQL in your view definitions.
| Attribute | Description | Example |
|---|---|---|
@@sql("...") |
The SQL query that defines the view | @@sql("SELECT * FROM users") |
@@materialized |
Create as materialized view (PostgreSQL) | @@materialized |
@@map("name") |
Custom view name in database | @@map("user_statistics") |
@@refreshInterval |
Auto-refresh interval for materialized views | @@refreshInterval("1h") |
@@parameterized |
View accepts runtime parameters | @@parameterized |
Views inherit the performance characteristics of their underlying queries. Ensure proper indexes exist on columns used in WHERE clauses, JOINs, and GROUP BY.
If a view performs expensive aggregations over large datasets, consider making it materialized and refreshing on a schedule rather than computing on every query.
Create multiple focused views rather than one complex view. This improves maintainability, performance, and makes the API clearer.