I was migrating a huge, high traffic WordPress site for a client on Codeable to Kinsta. Unfortunately they didn’t have FTP access or details so I had to get creative. Luckily, they were using VaultPress so I could generate a backup zip to download from there. Much to my surprise, I learned that the database backup was split into separate SQL files for each database table – there were over 150 of them!
I knew I didn’t want to import them manually so I thought I’d use WP-CLI to batch import them all automatically for me using the Linux command line.
This should work as long as you have SSH access on Debian, Ubuntu, CentOS etc.
How to Batch Import WordPress MySQL Table Dumps with or without WP-CLI
The first Linux script for importing all of your WordPress table .sql files is with WP-CLI.
If for some reason WP-CLI isn’t available you can use the version further down.
Importing Multiple WordPress Database Table Dumps with WP-CLI
You should define the absolute path to the WordPress installation, here it is /var/www/wp-bullet.com
.
This script assumes you have all of the database table dump files in an sql
folder.
# define WordPress path
WPPATH="/var/www/wp-bullet.com"
# loop through all of the
for DUMP in sql/*.sql;
do
wp db import ${DUMP} --allow-root --path=${WPPATH}
done
If you would like to know how long it takes to import all of the database tables add the time
command before the for
loop
# define WordPress path
WPPATH="/var/www/wp-bullet.com"
# extract database host and credentials
time for DUMP in sql/*.sql;
do
#[ -f "$DUMP" ] || break
wp db import ${DUMP} --allow-root --path=${WPPATH}
done
The output will look something like this when time
is added, I focus on the real
parameter
real 39m12.653s
user 2m49.977s
sys 5m2.513s
You can also find out the time taken for each table by adding time
before the wp db import
command
# define WordPress path
WPPATH="/var/www/wp-bullet.com"
# extract database host and credentials
time for DUMP in sql/*.sql;
do
#[ -f "$DUMP" ] || break
time wp db import ${DUMP} --allow-root --path=${WPPATH}
done
Just for fun let’s do it without WP-CLI as well
Importing Multiple WordPress Database Table Dumps without WP-CLI
Here is the script adjusted to work without WP-CLI. We use awk
to grab the MySQL database values 🙂
# define WordPress config path
WPCONFIG="/var/www/wp-bullet.com/wp-config.php"
# extract database host and credentials
DBHOST=$(grep DB_HOST "$WPCONFIG" | awk -F ["'"] '{ print $4 }')
DBUSER=$(grep DB_USER "$WPCONFIG" | awk -F ["'"] '{ print $4 }')
DBPASS=$(grep DB_PASSWORD "$WPCONFIG" | awk -F ["'"] '{ print $4 }')
DBNAME=$(grep DB_NAME "$WPCONFIG" | awk -F ["'"] '{ print $4 }')
# processes all sql files in the sql folder e.g. sql/table-name.sql
for DUMP in sql/*.sql;
do
[ -f "$DUMP" ] || break
mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} --force < ${DUMP}
done
Adding time
to find out how long each table is taking to import
# define WordPress config path WPCONFIG="/var/www/wp-bullet.com/wp-config.php" # extract database host and credentials DBHOST=$(grep DB_HOST "$WPCONFIG" | awk -F ["'"] '{ print $4 }') DBUSER=$(grep DB_USER "$WPCONFIG" | awk -F ["'"] '{ print $4 }') DBPASS=$(grep DB_PASSWORD "$WPCONFIG" | awk -F ["'"] '{ print $4 }') DBNAME=$(grep DB_NAME "$WPCONFIG" | awk -F ["'"] '{ print $4 }') time for DUMP in sql/*.sql; do time mysql -u ${DBUSER} -p${DBPASS} ${DBNAME} --force < ${DUMP} done
With either script you will get a long output list, keep an eye out for errors!
Success: Imported from 'sql/wp_cb_contests.sql'.
Success: Imported from 'sql/wp_cb_links.sql'.
Success: Imported from 'sql/wp_cb_prizes.sql'.
Success: Imported from 'sql/wp_cb_referrals.sql'.
Success: Imported from 'sql/wp_cb_user_contests.sql'.
Success: Imported from 'sql/wp_cleantalk_sfw_logs.sql'.
Success: Imported from 'sql/wp_cleantalk_sfw.sql'.
Success: Imported from 'sql/wp_cntctfrm_field.sql'.
Success: Imported from 'sql/wp_commentmeta.sql'.
Success: Imported from 'sql/wp_comments.sql'.
Success: Imported from 'sql/wp_contest_domination_entries.sql'.
Success: Imported from 'sql/wp_contest_domination_submissions.sql'.
Success: Imported from 'sql/wp_email.sql'.
Success: Imported from 'sql/wp_eshop_base_products.sql'.
Success: Imported from 'sql/wp_eshop_countries.sql'.
Success: Imported from 'sql/wp_eshop_discount_codes.sql'.
Success: Imported from 'sql/wp_eshop_download_orders.sql'.
Success: Imported from 'sql/wp_eshop_downloads.sql'.
Success: Imported from 'sql/wp_eshop_emails.sql'.
Success: Imported from 'sql/wp_eshop_option_names.sql'.
Success: Imported from 'sql/wp_eshop_option_sets.sql'.
Success: Imported from 'sql/wp_eshop_order_items.sql'.
Success: Imported from 'sql/wp_eshop_orders.sql'.
Success: Imported from 'sql/wp_eshop_rates.sql'.
Success: Imported from 'sql/wp_eshop_states.sql'.
Success: Imported from 'sql/wp_eshop_stock.sql'.
Success: Imported from 'sql/wp_et_social_stats.sql'.
Success: Imported from 'sql/wp_fbFreshCampaigns.sql'.
Success: Imported from 'sql/wp_fbFreshLinks.sql'.
Success: Imported from 'sql/wp_fbFreshLogs.sql'.
Success: Imported from 'sql/wp_fbFreshOG.sql'.
Success: Imported from 'sql/wp_forum_forums.sql'.
Success: Imported from 'sql/wp_forum_groups.sql'.
Success: Imported from 'sql/wp_forum_posts.sql'.
Success: Imported from 'sql/wp_forum_threads.sql'.
Success: Imported from 'sql/wp_forum_usergroup2user.sql'.
Success: Imported from 'sql/wp_forum_usergroups.sql'.
Success: Imported from 'sql/wp_gallery_galleriesslides.sql'.
Success: Imported from 'sql/wp_gallery_galleries.sql'.
Success: Imported from 'sql/wp_gallery_slides.sql'.
Success: Imported from 'sql/wp_gdsr_data_article.sql'.
Success: Imported from 'sql/wp_gdsr_data_category.sql'.
Success: Imported from 'sql/wp_gdsr_data_comment.sql'.
Success: Imported from 'sql/wp_gdsr_ips.sql'.
Success: Imported from 'sql/wp_gdsr_moderate.sql'.
Success: Imported from 'sql/wp_gdsr_multis_data.sql'.
Success: Imported from 'sql/wp_gdsr_multis.sql'.
Success: Imported from 'sql/wp_gdsr_multis_trend.sql'.
Success: Imported from 'sql/wp_gdsr_multis_values.sql'.
Success: Imported from 'sql/wp_gdsr_templates.sql'.
Success: Imported from 'sql/wp_gdsr_votes_log.sql'.
Success: Imported from 'sql/wp_gdsr_votes_trend.sql'.
Success: Imported from 'sql/wp_google_ads.sql'.
Success: Imported from 'sql/wp_httpbl_log.sql'.
Success: Imported from 'sql/wp_itsec_lockouts.sql'.
Success: Imported from 'sql/wp_itsec_log.sql'.
Success: Imported from 'sql/wp_itsec_logs.sql'.
Success: Imported from 'sql/wp_itsec_temp.sql'.
Success: Imported from 'sql/wp_layerslider.sql'.
Success: Imported from 'sql/wp_links.sql'.
Success: Imported from 'sql/wp_lockdowns.sql'.
Success: Imported from 'sql/wp_login_fails.sql'.
Success: Imported from 'sql/wp_mainwp_stream_context.sql'.
Success: Imported from 'sql/wp_mainwp_stream_meta.sql'.
Success: Imported from 'sql/wp_mainwp_stream.sql'.
Success: Imported from 'sql/wp_mc4wp_log.sql'.
Success: Imported from 'sql/wp_nivoslider4wp.sql'.
ERROR 1062 (23000) at line 3732 in file: 'sql/wp_options.sql': Duplicate entry 'itsec-lock-cron_test_fail_safe' for key 'option_name'
Success: Imported from 'sql/wp_options.sql'.
Success: Imported from 'sql/wp_panoramio.sql'.
Success: Imported from 'sql/wp_pmxe_exports.sql'.
Success: Imported from 'sql/wp_PO_groups.sql'.
Success: Imported from 'sql/wp_PO_post_plugins.sql'.
Success: Imported from 'sql/wp_popshops.sql'.
Success: Imported from 'sql/wp_postmeta.sql'.
Success: Imported from 'sql/wp_posts.sql'.
Success: Imported from 'sql/wp_PO_url_plugins.sql'.
Success: Imported from 'sql/wp_ratings.sql'.
Any tips how I can export SQL from 1 site (production) and import into another site (staging) using WP CLI? I want to automate my devops 🙂
Hey Chris, is it just specific tables you want to copy over and replace from staging to production or are you trying to merge changes?
Yes, merge! Maybe I wasn’t clear, my bad.
That’s a bit of a dark art Chris. Delicious Brains (https://deliciousbrains.com/) actually tried to do this with their Mergebot product and they did manage to get the product out but ultimately they were unsatisfied with it so it’s actually being pulled from their catologu. I script these tailored merge systems for clients myself, seems to be the only reliable way to do it 🙂