Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 31 of the WordPress Plugin Development: Foundations (PHP & MVC) course
WordPressJune 25, 20263 min read

Handling Plugin Updates: Database Schema and Migration Strategies

Learn to manage plugin updates effectively by tracking version numbers, implementing dbDelta for schema changes, and running one-time migration scripts.

WordPressPHPDatabaseUpdatesMigrationSchemaVersioningplugin-development

Previously in this course, we built a robust Model Layer for Data to abstract our database interactions. Now that our plugin is growing, we need a reliable way to evolve our database structure as we add features.

Software is never finished. When you release a new version of your plugin, you often need to change the database schema or reorganize existing data. Unlike Laravel migrations which are highly structured, WordPress requires us to manually manage the plugin version and trigger the necessary updates.

Tracking Plugin Versioning

The first step in managing updates is knowing which version of your plugin is currently installed. WordPress stores the plugin version in the header of your main plugin file, but that doesn't help your code know if it needs to run an update.

We store the "installed version" in the wp_options table. This allows us to compare the version in our code against the version saved in the database.

PHP
#6A9955">// Inside your main plugin class or activation/upgrade handler
public function check_for_updates() {
    $installed_version = get_option('my_kb_plugin_version', '0.0.0');
    $current_version = '1.1.0';

    if (version_compare($installed_version, $current_version, '<')) {
        $this->run_upgrades($installed_version);
        update_option('my_kb_plugin_version', $current_version);
    }
}

Implementing Schema Updates with dbDelta

When you need to add a column or create a new table, you shouldn't run raw CREATE TABLE queries directly. Instead, use dbDelta(). This function parses your SQL and compares it against the existing database schema, only applying the necessary changes.

It is strict about formatting:

  • You must put each field on its own line.
  • You must include the PRIMARY KEY definition.
  • You must use two spaces for keywords like BIGINT or NOT NULL.
PHP
function my_kb_update_schema() {
    global $wpdb;
    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    $table_name = $wpdb->prefix . 'kb_articles';
    $charset_collate = $wpdb->get_charset_collate();

    $sql = "CREATE TABLE $table_name (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        title varchar(255) NOT NULL,
        content text NOT NULL,
        version_added varchar(10) DEFAULT '1.0.0',
        PRIMARY KEY(id)
    ) $charset_collate;";

    dbDelta($sql);
}

Running One-Time Upgrade Scripts

Sometimes a schema change isn't enough; you might need to move data from a legacy format to a new structure. We handle this by checking the installed version and executing specific migration methods.

PHP
private function run_upgrades($installed_version) {
    #6A9955">// If the user is upgrading from a version older than 1.1.0
    if (version_compare($installed_version, '1.1.0', '<')) {
        #6A9955">// Run migration logic: e.g., move data from post_meta to custom table
        global $wpdb;
        $wpdb->query("UPDATE {$wpdb->prefix}kb_articles SET version_added = '1.1.0'");
    }
}

Hands-on Exercise

  1. Locate your main plugin class.
  2. Add a check_for_updates() method that compares your plugin's current version constant against an option in wp_options.
  3. Hook this method into the admin_init action so it runs when an administrator visits the dashboard.
  4. Create a run_upgrades() method that adds a new column to your Knowledge Base table using dbDelta.

Common Pitfalls

  • Forgetting dbDelta formatting: If you don't use the exact spacing requirements (like two spaces before PRIMARY KEY), dbDelta will fail silently or recreate tables unnecessarily.
  • Running migrations on every request: Always use version_compare to ensure your migration logic only runs once during the upgrade process.
  • Not using require_once: dbDelta is defined in wp-admin/includes/upgrade.php, which is not loaded by default on the frontend. You must include it manually.

Managing updates is a foundational skill for any professional WordPress plugin architecture. By versioning your database changes, you ensure that your users have a seamless transition between plugin releases without losing their data.

Up next: Internationalization (i18n) — preparing your plugin for global audiences.

Previous lessonCapability ChecksNext lesson Internationalization (i18n)
Back to Blog

Similar Posts

WordPressWordPressJune 25, 20263 min read

Capability Checks: Securing WordPress Plugins with Authorization

Master WordPress security by implementing capability checks. Learn to use current_user_can to restrict admin features and enforce proper access control.

Read more
WordPressWordPressJune 25, 2026

Part of the course

WordPress Plugin Development: Foundations (PHP & MVC)

beginner · Lesson 31 of 47

  1. 1

    Plugin Anatomy and File Structure

    3 min
  2. 2

    The Plugin Lifecycle Hooks

    4 min
  3. 3

    Designing for MVC in WordPress

    3 min
4 min read

Understanding WordPress Hooks: Actions vs. Filters Explained

Master the WordPress event-driven architecture. Learn the difference between actions and filters and how to implement callbacks to build robust plugins.

Read more
WordPressJune 25, 20263 min read

Caching Strategies: Mastering Transients for WordPress Performance

Learn how to use WordPress transients to cache expensive database queries. Boost your plugin's speed and reduce database load with proper invalidation logic.

Read more
4

Defining the Plugin Core Class

4 min
  • 5

    Understanding WordPress Hooks

    4 min
  • 6

    Implementing Custom Action Hooks

    4 min
  • 7

    Managing Hook Priorities

    3 min
  • 8

    Creating Admin Menus

    3 min
  • 9

    The Controller Layer for Admin Pages

    3 min
  • 10

    Registering Custom Post Types

    3 min
  • 11

    Configuring CPT Arguments

    3 min
  • 12

    Introduction to Taxonomies

    3 min
  • 13

    Designing Meta-Boxes

    3 min
  • 14

    Sanitizing User Input

    4 min
  • 15

    Saving Meta Data

    3 min
  • 16

    Database Basics with wpdb

    3 min
  • 17

    Secure CRUD Operations

    3 min
  • 18

    Querying with WP_Query

    3 min
  • 19

    Optimizing Queries

    3 min
  • 20

    The Model Layer for Data

    3 min
  • 21

    Enqueuing Scripts and Styles

    3 min
  • 22

    Plugin Template Hierarchy

    3 min
  • 23

    Creating Frontend Templates

    3 min
  • 24

    Building Shortcodes

    3 min
  • 25

    Advanced Shortcode Logic

    3 min
  • 26

    Introduction to Gutenberg Blocks

    3 min
  • 27

    The Settings API

    3 min
  • 28

    Validating Settings

    3 min
  • 29

    Implementing Nonces

    3 min
  • 30

    Capability Checks

    3 min
  • 31

    Handling Plugin Updates

    3 min
  • 32

    Internationalization (i18n)

    3 min
  • 33

    Debugging WordPress Plugins

    4 min
  • 34

    Unit Testing Foundations

    3 min
  • 35

    Handling AJAX Requests

    3 min
  • 36

    REST API Integration

    3 min
  • 37

    Advanced Database Queries

    3 min
  • 38

    Caching Strategies

    3 min
  • 39

    Plugin Security Best Practices

    Coming soon
  • 40

    Composer for Dependencies

    Coming soon
  • 41

    Theme Integration Hooks

    Coming soon
  • 42

    Managing Assets with Gulp/Webpack

    Coming soon
  • 43

    Documentation Standards

    Coming soon
  • 44

    Plugin Deployment Strategy

    Coming soon
  • 45

    Advanced MVC: Dependency Injection

    Coming soon
  • 46

    Handling Large Datasets

    Coming soon
  • 47

    Error Handling and Logging

    Coming soon
  • View full course