In yesterday’s post, I toured a few options for WordPress migration. I still like the look of VersionPress because the full clobber of most solutions out there feels horribly crude for ongoing development.

In the meantime, though, I want to get the content from this blog into my development environment — just to take a look. I circled back to the wp-cli documentation just in case – and I found the search-replace command. I have been looking at the db commands all this time — I must have passed by the very thing I want tens of times.

search-replace performs a find/change operation for you within the WordPress database. It comes with a host of other options and, best of all, it handles values in serialized data – always a gotcha. You can have your alterations applied in-place or output in a dump file. That’s what I need. So let’s get on.

Of course, nothing is ever as simple as it should be. The current getInstance site runs on a pretty old platform. So I have to start off by upgrading it to the minimum version that wp-cli supports:

$ wp core download --version=3.7 --force
Downloading WordPress 3.7 (en_US)...
md5 hash verified: aaad36cd739b825952cf3e09de5e7856
Cleaning up files...
File removed: wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.min.js
File removed: wp-admin/js/custom-fields.min.js
File removed: wp-admin/js/categories.js
File removed: wp-admin/js/custom-fields.js
File removed: wp-admin/js/cat.js
File removed: wp-admin/js/cat.min.js
File removed: wp-admin/js/categories.min.js
7 files cleaned up.
Success: WordPress downloaded.

The --force option lets wp-cli overwrite or delete existing files. Next I check that that the site has not blown up in some way and everything is more or less in place – which seems to be the case. So far so good. Now to generate my dump file (output edited):

$ wp search-replace '' '' --export=test.sql
| Table                 | Column                | Replacements | Type |
| gi_commentmeta        | meta_id               | 0            | PHP  |
| gi_commentmeta        | comment_id            | 0            | PHP  |
| gi_users              | display_name          | 0            | PHP  |
Success: Made 396 replacements and exported to test.sql.

So now I have an SQL dump file named test.sql. I copy that (and my wp-content/uploads directory) across to my development server. Now to install the SQL data. In my new space, wp-cli was installed by Composer, so I use a path to that:

$ ./vendor/bin/wp db import test.sql --path=site/wp/

Well, that seemed to work. Of course, when I load up the page… horrors! The white screen of doom!

I should have expected this. My new site is organised in a particular way – with WordPress in a subdirectory and with an external wp-content. The imported data includes configuration that knows nothing about any of this.

I need to recreate some settings. First of all, I should tell WordPress to use my site/wp directory:

./vendor/bin/wp option update siteurl --path=site/wp

Next, I need to set up post permalinks.

$ ./vendor/bin/wp rewrite structure /%postname%/ --path=site/wp
Success: Rewrite rules flushed.
Success: Rewrite structure set.

And that’s still not everything. I don’t use the Twenty Seventeen theme on the old version of the site so the imported data will tell WordPress to use my old theme. I could go into the admin screens and use the GUI to select my new theme but where’s the fun in that?

A quick pause. Apparently I am the kind of person who finds the command line fun. Oh well.

Anyway, here is the command I use to set the theme:

./vendor/bin/wp theme activate twentyseventeen-gi-child --path=site/wp
Success: Switched to 'getInstance child' theme.

Now for the real moment of truth.


So that worked – more or less. Well enough to justify a celebration with a cup of tea and a digestive biscuit.

But will I have to go through all this palaver every time I decided to migrate my database from one site to another? In fact, the process will generally be much easier because the configuration of source and target sites will typically be similar, with site content being the most likely to have changed from migration to migration.

That said, a complete database migration is a very blunt instrument. It’s fine for a one-off copy, but it won’t work well with two or three development environments while generation rolls along in production. There has to be a better way. More on that to come.

photo credit: josephmatthews IMG_1545 via photopin (license)