How to Use Init Hooks in Odoo 17

December 17, 2025 by
How to Use Init Hooks in Odoo 17
Widuri Sugiyani
| No comments yet

Introduction

In Odoo 17, init hooks are a powerful mechanism that allows developers to execute Python logic automatically when the module is installed. They are especially useful when you need to: 

  • Create or modify database-level objects (SQL functions, views, triggers) 
  • Perform data preparation or cleanup 
  • Ensure system consistency outside of ORM-managed models .


Understanding Init Hooks in Odoo 17

init hook is a special method in Odoo models that gets executed once per model when the module is first installed. Odoo provides several lifecycle hooks that can be defined inside a module:

Hook TypeWhen It Runs
post_init_hookAfter module installation
uninstall_hookWhen module is uninstalled
pre_init_hookBefore module installation

These hooks are declared in the module’s manifest.py file and must point to Python functions.


Implement Init Hooks 

In my case, I have a PostgreSQL function called:get_inventory_age_breakdown_data. This function is used to calculate inventory age breakdown data based on Company, Product, Category, Breakdown days and Checkpoint time

Because this logic is complex and performance-critical, it was implemented directly as a PostgreSQL function, not using Odoo ORM. That means:

  • The function must exist when the module is installed
  • The function must be removed when the module is uninstalled

This is a perfect use case for init hooks.


Creating the PostgreSQL Function (Post-Init Hook)

First, created a helper function to create or replace the SQL function.

def create_get_stock_age_breakdown_data_sgeede(env):
    query = """
        CREATE OR REPLACE FUNCTION public.get_inventory_age_breakdown_data(
            company_ids INTEGER[],
            product_ids INTEGER[],
            category_ids INTEGER[],
            breakdown_days INTEGER,
            checkpoint_time TIMESTAMP
        )
        -- SQL logic here
    """
    env.cr.execute(query)

Why CREATE OR REPLACE? 

Using CREATE OR REPLACE FUNCTION ensures: -

  • Safe reinstallation 
  • Safe module upgrade 
  • No error if the function already exists


Deleting the PostgreSQL Function (Uninstall Hook)

Next, created a cleanup function that drops the SQL function when the module is uninstalled.

def delete_stock_age_breakdown(env):
    query = """
        DROP FUNCTION public.get_inventory_age_breakdown_data(
            company_ids INTEGER[],
            product_ids INTEGER[],
            category_ids INTEGER[],
            breakdown_days INTEGER,
            checkpoint_time TIMESTAMP
        )
    """
    env.cr.execute(query)

This ensures there are no leftover database objects after module removal. 

⚠️ Important: PostgreSQL requires the function signature to match exactly when dropping a function.


Defining the Init Hook Functions

Now,  wrapped those helpers into hook functions that Odoo can call.

def _sgeede_post_init(env):
    create_get_stock_age_breakdown_data_sgeede(env)


def _sgeede_uninstall_init(env):
    delete_stock_age_breakdown(env)

These functions are intentionally kept small and clean, delegating the real logic to helper methods.


Registering Hooks in manifest.py

To make Odoo aware of these hooks, they must be declared in the module manifest:

{
    'name': 'Inventory Age Breakdown',
    'version': '17.0.1.0.0',
    'depends': ['stock'],
    'post_init_hook': '_sgeede_post_init',
    'uninstall_hook': '_sgeede_uninstall_init',
}

Once this is done: 

  •  _sgeede_post_init runs automatically after installation 
  •  _sgeede_uninstall_init runs automatically during uninstall


Why Init Hooks Are Important

Using init hooks gives several advantages:

✅ Clean database lifecycle management

✅ No manual SQL execution

✅ Safe upgrades and reinstallations

✅ Better maintainability for complex SQL logic

Without hooks, developers often forget to clean up database-level objects, which can cause:

  • Conflicts
  • Unexpected behavior
  • Migration issues


Conclusion

Init hooks in Odoo 17 are essential when a module interacts directly with the database outside the ORM. In this real case, they allowed me to safely manage a PostgreSQL function used for inventory aging calculations—automatically created during installation and properly removed on uninstallation.

If you are working with SQL functions, views, or triggers, init hooks should be part of your standard development pattern. However, it is critical to understand that init hooks are designed only for one-time initialization and do not run during module updates. Knowing this limitation helps avoid outdated database logic and ensures a clean, maintainable module lifecycle.

How to Use Init Hooks in Odoo 17
Widuri Sugiyani December 17, 2025
Share this post
Archive
Sign in to leave a comment