Skip to Main Content
Menu
Close Menu

Updating deprecated db_insert(), db_query(), db_select() calls in Drupal 8

Summary

This covers only the most common use cases.

Replace:

db_query('select * from user');

With:

\Drupal::database()->query('select * from user');

Replace:

db_insert('user');

With:

\Drupal::database()->insert('user');

Replace:

db_select('user');

With:

\Drupal::database()->select('user');

A little more information

Additional method arguments

Each of these methods has a different set of arguments, but the new class methods take the same arguments in the same order. You should be able to copy the arguments and use the new class methods.

Replace:

db_select('user', 'u');

With:

\Drupal::database()->select('user', 'u');

Using non-default database connections

These methods allowed you to set a target option which would use a different database connection. The new service does not allow passing in a database to connect to non-default databases. Instead, you can use a different service.

Replace:

db_select('user', 'u', [
  'target' => 'my_non_default_database',
]);

With:

\Drupal\core\Database\Database::getConnection('my_non_default_database')->select('user', 'u', []);

If you are using this method in a class, you can add a use statement:

use Drupal\Core\Database\Database;

Accessing the database when the container is not available

If you need to access the database before the container and its services are available, you can use the \Drupal\core\Database\Database::getConnection() method shown above.

More complex updates

If you would like to use dependency injection, you will need to inject the database connection service yourself. This service is called database and uses the \Drupal\Core\Database\Connection class.

Unfortunately, dependency injection patterns for services, controllers, and plugins (example: block plugin) are different. See https://github.com/damontgomery/d8_examples/tree/develop/d8e_service_dependency_injection for some examples of how dependency injection looks for these.

More examples

We have a set of examples as part of the Drupal Rector rector_examples module. See https://github.com/palantirnet/drupal-rector/tree/master/rector_examples.

Automating updates with Drupal Rector

Drupal Rector is an open source tool built using Rector which can help automate this deprecation as well as other common deprecations.

For more information, see https://github.com/palantirnet/drupal-rector.

What is covered by the rector

Drupal Rector replaces calls using \Drupal::database() which assumes the container is available.

When the $options array has a target key and is passed in-line, which is used to access other databases, Drupal Rector uses \Drupal\core\Database\Database::getConnection($database) to get that database. The \Drupal::database() doesn’t provide the option to use non-default databases.

Improvement opportunities

Drupal Rector does not handle variables used to specify the target option

Example:

$options = ['target' => 'default'];
db_query($query, $args, $options);

Drupal Rector does not inject the database connection into classes.

Drupal Rector does not check if the container is available and use Database::getConnection() instead of \Drupal::database().

Deprecation background

These deprecations used global method calls rather than a service, making unit testing more difficult.

References

The Drupal change record for this deprecation is available at https://www.drupal.org/node/2993033

Credits and thank yous

Thank you to Adam Bergstein for initial work on db_query. This rector was used as the basis for the one included in Drupal Rector.

Thank you to Dan Montgomery for leading Drupal Rector development to support this deprecation.

Thank you to Palantir.net for sponsoring this development.

Let’s work together.

Have an exceptional idea? Let's talk and see how we can help.
Contact Us