Repository navigation
query shouldn't require mysql/mariadb cli tools #319
Description
Activity
- addedhelp-wantedExtra attention is neededExtra attention is needed
on Apr 2, 2026 Most of the db commands, including
wp db query, also work when WordPress is not installed yet but the database is around, hence the current requirement of the binaries being installed.We could try falling back to loading WordPress, either implicitly or via an explicit flag such as
--load-wordpressthat would callRunner::load_wordpress(), sowpdbwould be available. Or some custom loading such as we currently do for SQLite inmaybe_load_sqlite_dropin(), which loads just a few files.For HyperDB, see also:
- removedhelp-wantedExtra attention is neededExtra attention is needed
on Apr 2, 2026 - linked a pull request that will close this issueAdd wpdb fallback for `wp db query` and `wp db import` when mysql/mariadb binary is unavailable #320
on Apr 2, 2026 Studio 1.14.0-dev22 reproduces this on a WordPress site using the SQLite database integration:
$ studio wp db query "SELECT 1;" Fatal error: Uncaught Error: Undefined constant "DB_HOST" .../vendor/wp-cli/db-command/src/DB_Command.php:1798
wp db queryruns atafter_wp_config_load, callsget_sql_mode_query(), then assumesDB_HOSTwhile constructing a MySQL command. The SQLite-backed site works normally; only this command fails. This is the same command-ownership gap described in closed #234, and supports the load-WordPress / SQLite-mode direction discussed here.No data was changed during reproduction.
I just ran into this on a live project, so here is a real-world data point.
Our server admins keep the webserver image minimal and simply do not install the
mysql/mariadbclient binaries. WordPress itself does not care, it talks to the database throughmysqlianyway. But everywp dbcommand that shells out is dead, andwp db querywas the one that hurt.The part that cost me the most time was the error message.
Utils\get_mysql_binary_path()returns an empty string when it finds nothing, and nobody checks that, so the command ends up as/usr/bin/env --no-defaults --no-auto-rehashand you get this:/usr/bin/env: illegal option -- nThat is not a great hint for "the mysql client is missing". Even without any fallback, a clear error here would already help a lot.
What we did instead was route everything through
$wpdb. This is from a multisite domain migration script, anonymised:# `wp db query` needs the mysql client binary, which the image does not ship, # so the statements go through WordPress' own $wpdb instead. SQL="UPDATE \`wp_2_options\` SET option_value='https://project.tld/blog' WHERE option_name='home';" \ wp eval --skip-plugins --skip-themes ' global $wpdb; $statements = array_filter( array_map( "trim", explode( "\n", (string) getenv( "SQL" ) ) ) ); foreach ( $statements as $statement ) { if ( false === $wpdb->query( $statement ) ) { WP_CLI::error( "failed: {$statement}: {$wpdb->last_error}" ); } } '
It works, but passing SQL through an env var into an inline PHP snippet to survive two layers of quoting is not something I want in a deploy script.
On the design question from your first comment: both options work for us. An automatic fallback when the binary is missing, or an explicit flag like
--use-php-for-db. I have no preference, the flag is arguably more predictable for CI, the automatic version means nobody has to change their scripts.One thing I would add to the scope:
db check,db optimizeanddb repairhit the same wall throughmysqlcheck, and those three map onto plainCHECK TABLE,OPTIMIZE TABLEandREPAIR TABLESQL. Same images, same problem, and no dump format to reimplement.db exportis the hard one, I would leave that alone.@swissspidy I saw #320 and left a review there. Happy to help with this, whether that means testing on our setup, writing the missing Behat scenarios, or picking up the branch in a fork and pushing the fixes. Just say what is most useful.
Thanks for sharing.
That error message is definitely not ideal, something we should fix either way.
I'll take another look at #320, though I have to say in your case I'd probably simply recommend installing the missing binary.
db-command was never intended to go through wpdb originally, so #320 creates a lot of complexity and discrepancy. I'm still on the fence about it.
Our ops team decided to keep the server setup minimal, so if the final decision would be to not implement it, I'd probably rather go with a custom CLI command.
If I can help somehow, feel free to contact me on Slack.
When
mysqlandmariadbCLI tools are unavailable,wp db queryshould fallback to using WPDB.This is particularly important when running with drop-in database engines, and multi-server/partitioned database drivers such as HyperDB.