In Odoo, performance analysis of the source code is more important. Database population is one of the methods used to analyze the performance of our code. We can use this feature to fill the database with a number of test data. And it will help to find the bugs or issues in the test. Odoo Command Line Interface (CLI) is used to accomplish the feature database population, and it will generate data automatically for the records of models to test the database containing a significant amount of records.
This blog will show how database population works in Odoo 17.
We can use some methods and attributes to populate a model.
* _populate_sizes(): This function will return a dictionary that maps the sizes ('small', 'medium', 'large'). Default sizes are small: 10, medium: 100, large: 1000
* _populate_dependencies(): This function will return dependent models of the current populating model. Those models will populate first before the current model.
* _populate(size): This function will create records to populate the corresponding model. The parameter size is a string that may be small, medium, or large.
* populate_factories(): This function will populate a factory for different fields of the corresponding model. And the factory is a dictionary of field values. It will return a list of pairs(field_name, factory) where `factory` is a generator function.
Example for Database Population:
We just want to define at least _populate(size) or _populate_factories() for the database population. Commonly, population functions and attributes for the models will be defined inside the populate directory of the module.
class ProductCategory(models.Model):
_inherit = "product.category"
_populate_sizes = {"small": 50, "medium": 500, "large": 5_000}
def _populate_factories(self):
return [("name", populate.constant('PC_{counter}'))]
def _populate(self, size):
categories = super()._populate(size)
# Set parent/child relation
self._populate_set_parents(categories, size)
return categories
def _populate_set_parents(self, categories, size):
_logger.info('Set parent/child relation of product categories')
parent_ids = []
rand = populate.Random('product.category+parent_generator')
for category in categories:
if rand.random() < 0.25:
parent_ids.append(category.id)
categories -= self.browse(parent_ids) # Avoid recursion in parent-child relations.
parent_childs = collections.defaultdict(lambda: self.env['product.category'])
for category in categories:
if rand.random() < 0.25: # 1/4 of remaining categories have a parent.
parent_childs[rand.choice(parent_ids)] |= category
for count, (parent, children) in enumerate(parent_childs.items()):
if (count + 1) % 1000 == 0:
_logger.info('Setting parent: %s/%s', count + 1, len(parent_childs))
children.write({'parent_id': parent})
In this example, the product.template model will be populated. For populating, we can use the command on the server:- odoo-bin populate –-models
Then, we can see the terminal while populating the models. Test records will be generated for all the models defined by the populate functions.
Here we populated records for product.category model, so we can go to the corresponding view and check the newly created records . Take product categories and we can see all the generated test records.
The marked records are created based on the database population. This way we can analyze the performance of our code with the help of a database population.