Available now: PostgreSQL and SQLite. Coming soon: MySQL and Microsoft SQL Server (MSSQL).
Start with a recipe
The recipe declares the logical structure. Asqueel resolves it into table and column objects. Building those objects does not open a database connection or create tables.
from asqueel import AsqueelDb
from invoicing import Invoicing
db = AsqueelDb(Invoicing)
invoice = db.table('invc.invoice')
Invoicing is the model used throughout the course. It contains customers, products, invoices, invoice rows and notes. Explore the recipe →
Describe a relationship once
A relation belongs to the model. Queries can follow that relation with an @ path. An alias column can give a frequently used path a name.
tbl.aliasColumn(
'customer_name',
relation_path='@customer_id.account_name',
)
Now every query on this table can refer to $customer_name. The compiler resolves the relation and generates the join. Follow the relations →
Keep calculations close to the data
A formula column describes a calculated value using SQL. It is queryable by name without adding a stored column.
tbl.formulaColumn(
'line_total',
sql_formula='$quantity * $unit_price',
dtype='N',
)
The course also covers correlated subqueries and aggregations over related rows. These examples use the development API described in the compatibility notes.
Inspect a query before executing it
SQL remains the expression language. Asqueel resolves model references; values are passed separately.
query = invoice.query(
columns='$inv_number, $customer_name, $total',
where='$total >= :minimum',
minimum=100,
order_by='$inv_number',
)
print(query.sqltext) # Compile without opening a connection.
rows = query.fetch() # Execute against the database.
Fetched rows are mutable NamedList objects with access by name or position. Use dict(row) when you need a dictionary. Choose a fetch terminal →
Use the same model for business logic
Table objects expose writes and can carry application behavior. The course follows what happens before and after an insert, update or delete: field triggers, table hooks and relation actions.
Transactions are explicit. db.commit() saves a unit of work. db.rollback() discards it. Understand the write cycle →
Choose the right boundary
| Concern | Responsibility |
|---|---|
| Tables, relations, formulas and query expressions | Asqueel |
| Synchronous reads, writes and transaction control | Asqueel |
| Comparing and applying physical schema changes | Asqueel Migration |
| Authentication, requests and application delivery | Your application |
| Rendering a user interface | Your UI framework |
The model can carry external metadata through grammar extensions. That does not imply a UI renderer or an authorization system. See the full course →