Working on a module that requires some database tables, I was not seeing my first testing table after installing and enabling the module. So I tried inserting some data into the table, and I got a backtrace (thank you xdebug) telling me that my table did not exist...

I have a little debugging logger that lets me append messages to a file, so I added some messages to my module's hook_install(); after repeated disables and enabling of my module, I am not getting any messages from hook_install(), so that leads me to believe it is never called. (FWIW, when the module is disabled, I can see the option to call it's uninstall routine on the admin/build/modules/uninstall page.) (Also, the debugging logger does work, I use it all the time.)

This brings up the question, when exactly is hook_install() called? After all, a module can be enabled and disabled via the admin/build/modules page, and one must travel explicitly to the admin/build/modules/uninstall page in order to uninstall a module...

Do I need to remove the module directory from my sites/all/modules directory, render some pages, and then copy the module's directory back in order to force identification that the module is "new" and then and only then the hook_install() is called? (hmmm... just tried that... did not do the trick.)

For reference, here's an abbreviated version of my moduleName.install file... See any issues?

<?php
// $Id$
/**
 * the flixor module's database schema
 * @file
 */
 
 /**
 * Implementation of hook_install()
 * @see http://api.drupal.org/api/function/hook_install/6
 * this is called when a module is installed, providing a chance
 * to create any database tables specific our module
 */
function flixor_install()
{
  _dbgReport( '****** flixor_install() called!' );

  drupal_install_schema( 'flixor_actor' );
}

/**
* Implementation of hook_uninstall()
* @see http://api.drupal.org/api/function/hook_uninstall/6
* this is called when a module is uninstalled, providing us with
* a chance to delete any tables and persistant variables
*/
function flixor_uninstall() 
{
  _dbgReport( '****** flixor_uninstall() called!' );
  
  // delete our database schema:
  drupal_uninstall_schema( 'flixor_actor' );
}

/**
 * Implementation of hook_schema()
 */
function flixor_schema() {
  $schema['flixor_actor'] = array( 
                             'description' => t('Maintain information for Flixor Actors.'),
                             'fields' => array(
                                                'nid' => array(
                                                                'description' => t('node id associated with this actor'),
                                                                'type' => 'int', 
                                                                'unsigned' => TRUE, 
                                                                'not null' => TRUE, 
                                                                'default' => 0
                                                              ),
                                                'vid' => array( 
                                                                'description' => t('version id associated with the node of this actor'),
                                                                'type' => 'int', 
                                                                'unsigned' => TRUE, 
                                                                'not null' => TRUE, 
                                                                'default' => 0
                                                              ),
                                                'aid' => array( 
                                                                'description' => t('actor id string associated with this actor'),
                                                                'type' => 'varchar', 
                                                                'length' => 127, 
                                                                'not null' => TRUE, 
                                                                'default' => ''
                                                              ),
                                                'stat' => array(
                                                                 'description' => t('internal use, tracks progress of use'),
                                                                 'type' => 'int', 
                                                                 'unsigned' => TRUE, 
                                                                 'not null' => TRUE, 
                                                                 'default' => 0
                                                               ),
                                                'label' => array(
                                                                  'description' => t('user supplied label'),
                                                                  'type' => 'varchar', 
                                                                  'length' => 127, 
                                                                  'not null' => TRUE, 
                                                                  'default' => ''
                                                                ),
                                              ),
                                'indexes' => array(
                                                    'aid' => array('aid'),    // most often lookups will be by aid or stat
                                                    'stat' => array('stat'),
                                                  ),
                                'primary key' => array('vid'), // Version is primary key. Could do nid, vid.
                              );

  return $schema;
}

Note: my real question is under what conditions is hook_install() called?

Comments

nevets’s picture

hook_install() is only called when a module is first installed

bsenftner’s picture

Please, Steve, that is hardly useful information.

I don't mean to offend, but how would I get my hook_install() called if I'm developing a module, have been adding functionality as I learn module development, and have just started to add the database logic, requiring me to write my module's hook_install() for the first time?

Do I need to uninstall it (even though no database tables were ever installed in the first place) in order for Drupal to then call hook_install()?

gbarrigap’s picture

Hi!

If the module was active before you created the schema, you need to reinstall it.

Are you using the Devel module?

http://drupal.org/project/devel

It offers you shortcuts to reinstall your modules.

Remember that if you change your schema once installed, the update functions will be required, in order to keep the database coherent.

Bye!

bsenftner’s picture

I must have something screwed up, because earlier today, before I starting adding the database logic, the devel module's disable/enable utility started causing an error when I used it. So I went back to just the manual disable and enabling via the admin/build/modules page, which did not cause any errors.

tomas.teicher’s picture

Where can I use that shortcut? I cannot find it

bsenftner’s picture

It's in the "Development" Block. After enabling the Devel.module, go to your blocks admin page (admin/build/block) and the "Development" block should be one of the unused blocks available at the bottom of the page. Once you've placed the block somewhere active, visit the page it appears and you'll find "Reinstall modules" in the middle of the menu that block presents.

Anonymous’s picture

It's solve my problem, who was the same as yours :
Dev a module, add a .install file, but don't know how to call my hook_schema method.

Use devel !!

amardhumal’s picture

hook_install() is only called first installation time.
If you installed the module and then uninstalled the module and you again installing the module then hook_install() does not call.
to call the hook_install() second installation do the following step:
1) go to mysql
2)execute following sql query:
DELETE FROM system WHERE type='module' AND name='your_module_name';
replace 'your_module_name' to your module name where .install file is there.

When you install the module first time one record get inserted into 'system' table.
when you uninstall the module 'status' column value of 'system' table get changed from 1 to 0.
If record is present in the 'system' table then hook_install() does not getting called.

Ajay Gadhavana’s picture

+1.
Perfect man. Its working for me.

amermod’s picture

7 years later, still useful !

bsenftner’s picture

I just tried uninstalling the module, to see if that would force hook_install() to be called. Of course, because the schema did not exist, calling my module's hook_uninstall() caused an error.

Then trying to enable the module again, I get a WSOD. Interesting to note, as you can see above in my flixor_install() version of hook_install, I have a _dbgReport() call before the drupal_install_schema() call, but I do not see my debugging message in my log, so that tells me that logic has not been hit when the WSOD occurs...

I can completely remove my module's flixor.install file, and everything "works", no WSOD... but, of course, I can't do anything requiring my database table...

nevets’s picture

You have the right process (install/uninstall/install repeat till working). The call to _dbgReport() could cause a problem.

bsenftner’s picture

This is the _dbgReport() utility, this would not cause a problem, would it?

function _dbgReport( $msg )
{
  $msg = $msg . "\n";
  file_put_contents( '/Users/bsenftner/demo/drupal_debugging_log.txt', $msg, FILE_APPEND );
}

hmmm... this lives inside the flixor.module file, but is referenced inside flixor.install... could _dbgReport() be out of context, undefined, when flixor.install is being used and flixor_install() called?

gbarrigap’s picture

That you are calling the drupal_install_schema and drupal_uninstall_schema with the string 'flixor_actor', which seems to be the name of the table you want to create, but these functions are suposed to receive the name of the module implementing the schema you need to create.

You should call these functions with the string 'flixor', the name of your module.

bsenftner’s picture

Thank you for catching that! I've made the correction, but after enabling my module I'm still getting a WSOD. Hmmm... I hate tracking down bugs like this.

gbarrigap’s picture

I just created a mini flixor module to test your schema, and it worked just fine. I think your problem is located in other file. If you want, you could paste your code to check it out.

bsenftner’s picture

Thanks for the offer, Guillermo, but the module is large, and full of proprietary, confidential logic. The module is of a type that will not ever become public because it implements a web API. Another, follow up module, will remotely access this module installed in a proprietary server offering complex media authoring facilities... see www.flixor.com to get an idea of what I building.

bsenftner’s picture

I seem to have made a breakthrough:

I made a local copy of my _dbgReport() function, renaming it _installReport(), and placing it inside the flixor.install file. Then I commented out calls to variable_del() that were getting rid of the persistent variable's I'd created. Plus, just to be safe, I commented out the entire contents of my hook_install(), hook_uninstall(), and moduleName_schema() routines...

Finally, I'm seeing in my debugging log the fact that flixor_install() is being called...

I think my getting rid of the persistent variables may be the problem. Don't know why... but adding them this afternoon was right around the time that the devel.module's uninstall/install utility started causing errors.

Bensbury’s picture

Hi,
I had the same trouble.

In the end I copied the install contents from the devel module and then wiped out all functions except install, uninstall and schema.

Then did a search and replace on 'devel' with the name of my module.

That worked.

So I uninstalled it and then slowly altered the devel schema into the schema I wanted.

After that no problems.

I have no idea why it wouldn't work but it looked like there was something wrong in my schema, and using devel's as a template made sure it worked.

amardhumal’s picture

hook_install() is only called first installation time.
If you installed the module and then uninstalled the module and you again installing the module then hook_install() does not call.
to call the hook_install() second installation do the following step:
1) go to mysql
2)execute following sql query:
DELETE FROM system WHERE type='module' AND name='your_module_name';
replace 'your_module_name' to your module name where .install file is there.

When you install the module first time one record get inserted into 'system' table.
when you uninstall the module 'status' column value of 'system' table get changed from 1 to 0.
If record is present in the 'system' table then hook_install() does not getting called.

Jaypan’s picture

It's not usually a good idea to touch the database with Drupal. You never know what modules are doing what with the database.

The safer way to do this is to disable your module, then uninstall it (from the uninstall tab on the modules page), then re-install it.

yixia’s picture

Install module:
Just check the checkbox and click save button.

Uninstall module:
Uncheck the checkbox, click the save button, and then go to the uninstall tab to uninstall the module

I log that the hook_install() and hook_uninstall() work everytime.

darrylmabini’s picture

This is the answer in my question. I never noticed the uninstall tab in the module page since the first time I used drupal. Thanks again, Smile^^.

rocqie’s picture

Uninstall the module.
Rename the module, and the hooks accordingly.
Reinstall the module.