Hooks & Execution¶
DBPort supports hook-based execution for model logic. A hook is a Python or SQL file that serves as the model's main entry point.
Running a model¶
Hook resolution order¶
Resolution precedence
When no explicit target is given, DBPort resolves the hook in this order:
- Configured hook path — set via
dbp config default hook main.pyin the model root — auto-detected if it existssql/main.sqlin the model root — legacy fallback- Default
main.py— used when no model root is available; errors at execution if the file does not exist
Python hooks¶
Python hooks are executed with port (the active DBPort instance) available in the namespace.
# main.py
from dbport import DBPort
def run(port: DBPort) -> None: # (1)!
port.schema("sql/create_output.sql")
port.load("estat.nama_10r_3empers", filters={"wstatus": "EMP"})
port.execute("sql/transform.sql")
if __name__ == "__main__": # (2)!
with DBPort(agency="test", dataset_id="output") as port:
run(port)
port.publish(version="2026-03-15")
- If a top-level
run(port)function is defined, it is called automatically after the module is loaded. This is the recommended pattern. - The
if __name__ == "__main__"block runs only when the file is executed directly. During CLI execution,__name__is set to"__dbport_hook__", so this block is skipped.
Inline execution¶
If no run(port) function is defined, the module body is executed directly with port in scope:
# main.py — inline style (simpler, but less reusable)
port.schema("sql/create_output.sql")
port.load("estat.data_table")
port.execute("sql/transform.sql")
SQL hooks¶
SQL hooks are passed directly to port.execute(). Use this for models that are pure SQL with no Python logic:
-- sql/main.sql
CREATE OR REPLACE TABLE output.result AS
SELECT geo, year, SUM(value) AS total
FROM input.raw_data
GROUP BY geo, year;
exec vs run vs publish¶
These three operations are distinct and composable:
| Command | What it does | Publishes data? |
|---|---|---|
dbp model exec |
Execute the configured hook | No |
dbp model run --version V |
Execute hook, then publish | Yes |
dbp model publish --version V |
Publish only (no execution) | Yes |
dbp model run is the full lifecycle command: sync → execute → publish.
| Method | What it does | Publishes data? |
|---|---|---|
port.execute(sql_or_path) |
Run a single SQL statement or file | No |
port.run(version="V") |
Resolve and execute the hook, then publish | Only if version given |
port.publish(version="V") |
Write the output table to the warehouse | Yes |
Trust model¶
Hooks are trusted code
Hook files run with the same permissions as the calling script or CLI process. There is no sandboxing — the hook is your model logic, authored by the model owner. This is the same trust boundary as any other user-authored Python module.