WordPress Query Recorder Plugin: Record and Save Queries to a SQL File for Deployment

Query Recorder is a new tool that allows developers to record queries while working in the WordPress admin. The plugin was created by Brad Touesnard, author of the popular WP Migrate DB plugin. Touesnard introduced Query Recorder earlier this month at WordCamp Miami during his presentation on database deployment strategy.

Once installed, the plugin allows you to create recordings that save queries run by your theme or plugins. The recordings are sent to a sql file located in your /uploads/ directory.

The settings page gives you the option to set exclusions for certain types of queries and elect to omit or record queries that begin with insert, update, delete, drop, and create.


Clicking the button in the admin bar will start or stop the recording:


Once you’ve made a recording, open up the SQL file in your uploads folder and you’ll find your saved queries. In the example below you can see that I’ve enabled and disabled some plugins and themes.


Query Recorder can be particularly useful when working on a local installation of WordPress. You can record queries as you’re setting up a theme or plugin and create a SQL script that can be run later when deploying to another site. You can quickly test plugins and themes and then import the sql file when setting them up on a staging or live site. This is much easier than having to repeat those exact steps again in another environment.

I tested the plugin and it works exactly as advertised. Download Query Recorder for free from the WordPress plugin directory. If you’d like to contribute to the project, it’s also hosted on Github.


11 responses to “WordPress Query Recorder Plugin: Record and Save Queries to a SQL File for Deployment”

  1. That’s a pretty cool plugin, although I always prefer to run the MySQL server with --general_log when debugging, that way I also catch the naughty plugins by-passing $wpdb calling mysql_query directly :)

    Quick note — queries are logged into a publicly accessible directory. This is a mistake many plugins do/did, even fairly popular ones like W3 Total Cache, which at some point stored database and object cache publicly accessible on disk. You definitely don’t want to leak your database queries, which can contain e-mails, password hashes, authentication tokens to external services like Twitter, Google, etc.

    • You beat me to it, Konstantin. Although you could, or course, update your .htaccess file to restrict access to the files publicly. Will add a support post on the plugin page to suggest it.

    • A few things about the security here…

      1. This plugin is for use on a dev site, which shouldn’t be publicly accessible anyways
      2. We add a salt to the default filename making it hard to guess
      3. The file path is the first option on the settings screen and can easily be adjusted

      The chances that PHP has write permission to the uploads folder is very good, so that’s why a lot of plugins use that location. However, this is a plugin for developers, so I’m open to the idea of changing the default path to be a non-public location, but how do you detect a non-public folder? Maybe the better course would be to not have a default and force them to choose a path?

      • Hey Brad, thanks for following up!

        2. We add a salt to the default filename making it hard to guess

        The salt is a 5-character long alpha-numeric string. If the web server is configured correctly, it’ll probably ignore case, so that’s a bit over 6M possibilities, which in bruteforce language is peanuts. If, however, the web server is configured incorrectly, it can spit out a directory index when accessing the uploads directory, making it even easier.

        The chances that PHP has write permission to the uploads folder is very good, so that’s why a lot of plugins use that location.

        Plugins should stop assuming anything has any permissions and use WP_Filesystem instead :)

        How do you detect a non-public folder?

        I’m not sure, perhaps you can try sys_get_temp_dir().

      • Hi Brad,

        All valid points, but it’s probably worth at least adding this information to the plugin README.txt file to make sure less knowledgable people using this plugin are aware, and your plugin is the one that causes them a security breach, just because you forgot to clarify.

  2. This is sweet! How many times have I wished I could do just this. Going to grab this now, thanks Sarah!

  3. Nice plugin and concept! When it comes to moving data between environments (cited as one of the use case) how do you account for possible differences of identifiers used in the WHERE clause such as the dynamically generated ones – user_id, id, etc… Or, do you assume they will be always the same across databases/environments?

    • Yep, that’s definitely an issue. The recorded queries are only really useful at the moment when there are no foreign keys involved. I’ve been considering a pro version that will resolve that issue though.

      • Support the core tables for sure to start and some of the major plugins that have custom tables like the ecommerce plugins. And of course provide an easy way to map out custom tables yourself.

        • I love the functionality and am sure will find a good use for the plugin within the same instance. Moving data across environments, however, is a totally different game. Hard, very hard, especially when you would be dealing with database schema over which you don’t have control. Good luck!


Subscribe Via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

%d bloggers like this: