node_load after switching database + cck = dangerous

While everyone agrees the node_load() function and the CCK and Content module are two fantastic things, be carefull using node_load when switching your database in code. The current database you're on doesn't necessarily know which modules are activated on the other database/site and what the properties are of the node you're trying to retrieve. This all makes sense to me now, but I had to learn this the hard way spending 8 hours debugging an enormous and enoying problem where data sometimes was completely corrupted coming back.

CCK uses its own cache table to store data to gain more performance. That's fine. Let's imagine we are on site A, create our node with many properties (hence, lot's of extra cck widgets) and save this to the database. We can look at it, edit etc, it will work just fine. Now, let's switch to our second site where we have a tiny little function which simply does this:

<?php
db_set_active
('siteA');
$node = node_load(1);
db_set_active('default'); // or siteB
?>

Everyone with a bit of Drupal knowledge will know we'll get a full node object back from the database. But there's a lot happening in the background: node_load, module_invoke_all('hook_load') invoking content_load in CCK and here's where things went wrong this afternoon. CCK has it's own hook system calling other cck widgets to know their properties and fields we associated with our node. When there's nothing cached, CCK builds it's own cached object with all existing fields etc, but when you call this from site B and say the 'filefield.module' isn't enabled, cck will not see this, thus leaving out any uploaded properties in the node object we want to retrieve (CCK will also miss other settings, but I don't want to elaborate on this to much). Yet, we have defined this filefield in site A before. What happens now in site A is simple: we view or edit our node, but we are now retrieving the cached cck object and we see missing properties ('see' is very ironic, but you get the point right?). Frustration is wat's left if you encounter this the first time.

Oh well, luckily the French fries were very good :)

Comments

Submitted by logon on April 27, 2010 - 13:33

There are also other types of databases which cannot be classified as relational databases. Most notable is the object database management system,icnd which stores language objects natively without using a separate data definition language and without translating into a separate storage schema.

Submitted by Chris on October 21, 2010 - 21:27

I ran into a similar issue where node_load() to alternate DB resulting in core fields coming over but not any CCK fields.

Here's how we fixed it:


function mymodule_switch_db($db) {
db_set_active($db);
cache_clear_all();
drupal_get_schema(NULL, TRUE);
}

Then I used node_load like this: node_load($nid, NULL, TRUE) and it grabbed all fields from old DB correctly.

You are here