Problem/Motivation
There are three ways to create tables based on Schema API:
- Implement
hook_schema()
: Schema is stored in code. - Create tables via Entity API: Schema stored in key/value store, under
entity.storage_schema.sql
collection. - Dynamically created with Database::getConnection()->schema()->createTable(): stored nowhere.
Right now if you want to inspect the schema for a table there's no way to do it in a consistent way:
- For module schema, you can use
drupal_get_module_schema()
- For entity tables schema you query the key/value store
- For dynamically created tables there's no way to do it.
You cannot ask: Hey, give me the schema for table {some_table_created_with_a_valid_schema} regardless of how the table has been created.
Proposed resolution
- Register/deregister dynamic table schema on creation/deletion in the key/value store in a new collection
sql_schema
(proposal) - Create a single point of inspecting DB schema by adding 2 new methods to
\Drupal\Core\Database\Schema
:::getSchema($table_name)
::getSchemaByModule($module, $table_name = NULL)
Both methods should aggregate all types of table created with a valid schema (from all 3 sources). For example it will be possible to get a result when querying:
// hook_schema() table. $schema = Database::getConnection()->schema()->getSchema('key_value'); // Entity API table. $schema = Database::getConnection()->schema()->getSchema('node_field_data'); // Dynamic created table. $schema = Database::getConnection()->schema()->getSchema('cache_bootstrap');
Persistent/statically cache the results of these new methods. Dynamically created tables will be owned by 'core' module.
- Optionally but recommended: Add an interface to
\Drupal\Core\Database\Schema
for existing and new methods. - Deprecate
drupal_get_module_schema()
& Co.
Remaining tasks
Discuss, fix, tests.
User interface changes
None.
API changes
- New methods in
\Drupal\Core\Database\Schema
- Potentially new interface for
\Drupal\Core\Database\Schema
.
Data model changes
New key/value collection: sql_schema
.
Comments
Comment #6
andypostComment #8
andypostComment #13
TR CreditAttribution: TR commenteddrupal_get_module_schema()
was removed in core 9.2 by #2908886: Split off schema management out of schema.incThere is now currently no API to get a table schema for any table. I consider this a regression, and this issue should probably now be a bug report rather than a feature request.
Use case:
There is nothing unusual or edge about this use case - just because not many modules do this does not mean it is wrong in any way. Drupal should and must have methods for dealing with non-Entity, non-Field data.
But for this use case to work, I MUST be able to create a new table with the same structure as the existing table. And for that I need the schema of the existing table. While I have
\Database::getConnection()->startTransaction()
,\Database::getConnection()->schema()->dropTable()
andDatabase::getConnection()->schema()->renameTable()
available for this purpose, creating the temporary table requires\Database::getConnection()->schema()->createTable()
which requires a schema for the created table. There is no way to obtain that schema anymore now thatdrupal_get_module_schema()
has been removed.The solution suggested in #2908886: Split off schema management out of schema.inc is to use
\Drupal\TestTools\Extension\SchemaInspector
, which is intended only for Tests. This is not a substitute for having schema introspection in core. The only other alternative is to call<modulename>_schema()
directly, which again is not a good solution.This issue proposes a solution that would work for my use case. It requires maintainer feedback. Part of this solution is to deprecated
drupal_get_module_schema()
, but that has already been done, and without a replacement, so IMO the priority of this issue should now be higher because functionality has disappeared.@claudiu.cristea, this is still assigned to you - are you intending to work on it?