Skip to main content
Home
Drupal life hacks

Main navigation

  • Drupal
  • React
  • WP
  • Contact
  • About
User account menu
  • Log in

Breadcrumb

  1. Home

Database Schema Definitions Replace Array-Based Schema API in Drupal 12

By admin, 3 August, 2026

Drupal 12 introduces one of the biggest improvements to the Database Schema API in years. The traditional nested array structure used to define database schemas is being replaced with a modern, object-oriented API built around immutable value objects.

This change makes schema definitions easier to validate, safer to extend, and opens the door for future database-specific capabilities without sacrificing Drupal's database abstraction.

Why Was This Changed?

For nearly two decades, Drupal developers have defined database tables using large nested arrays inside hook_schema() implementations.

While this approach has served Drupal well, it has several drawbacks:

  • No type safety
  • Difficult validation
  • Limited IDE autocompletion
  • Hard to extend without breaking compatibility
  • Database-specific options mixed with abstract schema definitions

Drupal 12 replaces these arrays with dedicated value objects located in the Drupal\Core\Database\SchemaDefinition namespace.

The new API is immutable, strongly typed, and much easier for both developers and static analysis tools to understand.

Before: Array-Based Schema Definitions

A typical table definition looked like this:

$schema['config'] = [
  'description' => 'The base table for configuration data.',
  'fields' => [
    'collection' => [
      'type' => 'varchar_ascii',
      'length' => 255,
      'not null' => TRUE,
      'default' => '',
    ],
    'name' => [
      'type' => 'varchar_ascii',
      'length' => 255,
      'not null' => TRUE,
      'default' => '',
    ],
  ],
  'primary key' => ['collection', 'name'],
];

Although familiar, this format relied on string keys and conventions that were difficult to validate.

After: Object-Oriented Schema Definitions

The same table is now represented using immutable value objects:

new Table(
  name: 'config',
  description: 'The base table for configuration data.',
  columns: [
    new Column(
      name: 'collection',
      type: ColumnType::VarcharAscii,
      length: 255,
      notNull: TRUE,
      default: new StringValue(''),
    ),
    new Column(
      name: 'name',
      type: ColumnType::VarcharAscii,
      length: 255,
      notNull: TRUE,
      default: new StringValue(''),
    ),
  ],
  primaryKey: new PrimaryKey(['collection', 'name']),
);

Several improvements are immediately noticeable:

  • Strongly typed classes instead of nested arrays
  • PHP named arguments improve readability
  • IDE autocompletion works much better
  • Invalid properties can be detected much earlier
  • Immutable objects eliminate accidental modification

hook_schema() Has Changed

The return type of hook_schema() is no longer an array.

Drupal 11 and Earlier

function mymodule_schema(): array {
  $schema['my_table'] = [
    // ...
  ];

  return $schema;
}

Drupal 12

function mymodule_schema(): Schema {
  return new Schema(
    type: SchemaDefinitionType::Module,
    name: 'mymodule',
    tables: [
      new Table(
        name: 'my_table',
        // ...
      ),
    ],
  );
}

Instead of returning an associative array, modules now return a Schema object containing one or more Table definitions.

Storage Schema Definitions Also Change

Custom storage handlers that previously returned arrays must now return Schema objects.

Creating tables has also changed.

Previous API

$this->connection
  ->schema()
  ->createTable($table_name, $schema_definition);

New API

$this->connection
  ->schema()
  ->createSchemaFromDefinition(
    $this->schemaDefinition()
  );

Likewise, schemaDefinition() now returns a Schema object instead of an array.

Benefits for Module Developers

The new API provides several practical advantages:

  • Better IDE support
  • Strong typing
  • Immutable schema definitions
  • Automatic validation of properties
  • Easier future API evolution
  • Cleaner, more readable code
  • Improved maintainability

Because the API uses PHP objects instead of magic array keys, refactoring becomes much safer and static analysis tools can detect many mistakes before code is executed.

Future Possibilities

Perhaps the most exciting aspect of this redesign is what it enables in future Drupal versions.

The old schema arrays contained database-specific field types such as varchar_ascii, making true database abstraction difficult.

With the new architecture, Drupal can separate generic schema definitions from database-specific implementations. This opens the possibility for database drivers to expose advanced features including:

  • PostgreSQL GIN indexes
  • PostgreSQL GiST indexes
  • Vendor-specific index options
  • Improved schema introspection
  • Better migration tooling
  • More powerful validation

The core schema definition remains database-independent while drivers can implement advanced capabilities behind the scenes.

Migration Considerations

This API change lands in Drupal 12 and is not backward compatible.

Module developers will eventually need to update:

  • hook_schema() implementations
  • Custom storage handlers
  • Installation schemas
  • Test schemas
  • Any code that dynamically creates database tables

Fortunately, the new API closely mirrors the concepts of the old one, making migration mostly mechanical.

Final Thoughts

The Database Schema Definition API is a significant modernization of one of Drupal's oldest subsystems.

Replacing fragile nested arrays with immutable value objects brings stronger typing, better tooling support, cleaner code, and a much more extensible architecture.

While module developers will need to update their schema definitions when adopting Drupal 12, the long-term benefits far outweigh the migration effort. This change lays a solid foundation for future database innovations while making everyday schema definitions easier to write and maintain.

Comments

About text formats

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Powered by Drupal