I have following code for creating table:
$sql = "CREATE TABLE " . $table_name . "("
. "id mediumint(9) NOT NULL AUTO_INCREMENT, "
. "product_id mediumint(9) DEFAULT 0 NOT NULL,"
. "name_type mediumint(9) NOT NULL, "
. "name_key varchar(48) NOT NULL, "
. "valid_until datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "updated_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "UNIQUE KEY id (id)"
. ")" . $charset_collate. ";";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
It is working and table created.
Now I need update table and add new column (sites_list):
$sql = "CREATE TABLE " . $table_name . "("
. "id mediumint(9) NOT NULL AUTO_INCREMENT, "
. "product_id mediumint(9) DEFAULT 0 NOT NULL,"
. "name_type mediumint(9) NOT NULL, "
. "name_key varchar(48) NOT NULL, "
. "sites_list longtext, "
. "valid_until datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "updated_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, "
. "UNIQUE KEY id (id)"
. ")" . $charset_collate. ";";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
But this not work.
And I has a error:
WordPress database error: [Table 'table_name' already exists]
What is incorrect?
Thanks.
You’ve used the dbDelta function incorrectly.
You have to put each field on its own line in your SQL statement.
You have to have two spaces between the words PRIMARY KEY and the definition of your primary key.
You must use the keyword KEY rather than its synonym INDEX and you must include at least one KEY.
http://hungred.com/how-to/wordpress-dbdelta-function/
The code itself of the dbDelta function is very complex. But with trial-and-error, I’ve noticed some behaviors of the dbDelta function update behavior:
Long explanation
dbDelta is a function that people usually tell to hook at
register_activation_hook
, but this doesn’t fire on plugin updates, so it wouldn’t create the tables for your users that are upgrading an existing install. So the first thing to get dbDelta updates to work, is to hook it onadmin_init
.However, this is a pretty heavy function, so it must only run when needed. For this, you can keep a
my_plugin_db_version
option in the database, and use it to check if you should run the dbDelta or not.If you already have an autoloaded option being loaded, it’s even better to use that, as the check will have zero performance impact, as autoloaded options are loaded in-memory at the beginning of WordPress life-cycle.
This, in code, can be expressed as:
Now let’s suppose that I have this dbDelta on version 1.0 of my plugin:
This produces the following DDL in the database:
Now I decide to rename
id
toevent_id
, so I change the dbDelta and release the version 1.1 of the plugin:This delta won’t change the db structure for users that are upgrading the plugin, they will have the primary key as
id
, while new installs will have the primary key asevent_id
:So rule #1 of dbDelta: It doesn’t renames the Primary Key column.
Now, on version 1.2, I want to rename
event
toevents
, so I modify the dbDelta like this:This will produce the following result for users that upgrade from 1.1 to 1.2:
While producing the following result for fresh installs:
While producing the following result for users that use the plugin since 1.0:
Which is a pretty reasonable behavior when you come to think about it. If you rename the column
event
toevents
, you can still migrate the data from the old column to the new for previous installs. Just remember to never rename the column that is assigned as Primary Key.