I am creating a custom module with its own schema of a few tables. These tables need to have some values pre-populated into them for the module to work (default locations, select options, etc).

What's the best practices way to insert default values into these tables during hook_install?

Since drupal_write_record is not available, I can use db_query, but I just want to make sure that I'm not breaking any cardinal rules by doing so.

2 Answers 2


The better way is to do it inside hook_enable(); at the time the hook is invoked, the module is already installed, and the schema of its database is available to Drupal, and to drupal_write_record(). As the hook is invoked all times a module is enabled, and not just when the module is installed, the hook implementation should check if it didn't added those database rows already (e.g., it should use a Drupal variable containing a boolean value).

As example of module that uses hook_enable() for a similar purpose, you can check forum_enable(), or php_enable() (which adds the "PHP code" input format).

function php_enable() {
  $format_exists = (bool) db_query_range('SELECT 1 FROM {filter_format} WHERE name = :name', 0, 1, array(':name' => 'PHP code'))->fetchField();
  // Add a PHP code text format, if it does not exist. Do this only for the
  // first install (or if the format has been manually deleted) as there is no
  // reliable method to identify the format in an uninstall hook or in
  // subsequent clean installs.
  if (!$format_exists) {
    $php_format = array(
      'format' => 'php_code', 
      'name' => 'PHP code',
      // 'Plain text' format is installed with a weight of 10 by default. Use a
      // higher weight here to ensure that this format will not be the default
      // format for anyone. 
      'weight' => 11, 
      'filters' => array(
        // Enable the PHP evaluator filter.
        'php_code' => array(
          'weight' => 0, 
          'status' => 1,
    $php_format = (object) $php_format;

    drupal_set_message(t('A <a href="@php-code">PHP code</a> text format has been created.', array('@php-code' => url('admin/config/content/formats/' . $php_format->format))));

As shown from those hook implementations, the code could necessarily need to be executed all times the hook is executed; it could also be the code needs to just executed once, as in the case the default values added to the database cannot be altered from the user, who doesn't have a user interface to alter/delete those values.

  • If I did this in hook_enable(), that means the default values would be reset every time that the module is enabled and disabled. I think that is fairly common, as opposed to completely un-installing and re-installing (at which point it is expected that the database gets reset).
    – oranges13
    Aug 17, 2011 at 14:22
  • 1
    That is why I wrote, "the hook implementation should check if it didn't add those database rows already." This means that it should check if the values are already in the database table, or use a Drupal variable to check if it is has already done that task. Checking the database table would be done if those values necessarily needs to be in the database; for example, this is the case if the values are required from the module, and the users are not allowed to remove the default values.
    – apaderno
    Aug 17, 2011 at 14:40
  • Thanks for the clarification. Is there any difference in storing these values in my own custom table vs. just using variable_set to store them in a persistent variable? It's just an array of values for custom select boxes.
    – oranges13
    Aug 17, 2011 at 14:43
  • All the values set using variable_set(), which are not deleted with variable_del(), are loaded in memory when Drupal bootstraps, and saved in a global variable; this means that they are in memory whatever the module is using those values, or not. Using a custom database table, you can be sure those values are only loaded when the module really needs it. You should not use variable_set() if the Drupal variable contains an array to which you keep adding a new array index all times, for example.
    – apaderno
    Aug 17, 2011 at 14:49
  • Looking at the code (D7). I only see 2 lines of code between the invocation of hook_install and hook_enable: an update to a local variable and a call to watchdog. So, during a real install, there is no difference whatsoever between these 2 hooks about what is available and registered and what not. The only difference is whether this is a first time install or just re-enabling the module.
    – fietserwin
    Jun 30, 2012 at 19:46

I'd go with db_query / db_insert (D6 / D7) in hook_install().

It's not considered bad practice (and nobody is ever forcing you to use drupal_write_record()).

It is not uncommon for people to disable and re-enable modules, and in that case your code in hook_enable() would fire each time. which is not nice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.