How Enterprise Executes Queries
Understanding the execution lifecycle of queries in Enterprise helps you write efficient code and debug complex database interactions.
Query Lifecycle Flow
Here is the step-by-step lifecycle of a database read operation (e.g., calling Get() on a model):
SQL Compilation: The model delegates execution to the core query builder in the
clientpackage. This engine translates model predicates, relations, limit, offset, and order parameters into a parameter-deduplicated SQL query string and apgx.NamedArgsmap.Observer Interception: If a
QueryObserveris set inOptions, itsBeforemethod is executed, which can mutate the context.Driver Invocation: The compiled SQL is run against the connection pool via pgx.
Post-Execution Interception: The
QueryObserver.Afterhook is executed with the operation result or error.Logging: If
Options.Debugis enabled, the query and its arguments are logged viaslog(JSON handler, LevelDebug).Result Scanning: The returned rows are scanned into the pre-allocated value pointers, and the model triggers its internal
ScanResulthook to finalize entity states.
Transactions and Savepoints
Enterprise supports block-based transactions. If a transaction is active, the model operations are executed using a Transaction client which implements the same DatabaseClient interface, ensuring seamless transaction integration.
err := db.Transaction(ctx, func(tx client.DatabaseTransactionClient) error {
account := models.NewAccount(ctx, tx)
account.SetName("Transacted Name")
return account.Create()
})