Reflection of Structure
Nette Database provides tools for database structure introspection using the class Nette\Database\Reflection\Reflection. This allows you to retrieve information about tables, columns, indexes, and foreign keys. Reflection can be used for schema generation, creating flexible database-driven applications, or general database tools.
You can obtain the reflection object from a database connection instance:
$reflection = $database->getReflection();
Working with tables
Using reflection we can browse all tables in the database:
getTables(): Nette\Database\Reflection\Table[]
Returns an associative array where the key is the table name, and the value is an array of table metadata.
// Listing all table names
foreach ($reflection->getTables() as $table) {
echo $table['name'] . "\n";
}
hasTable(string $name): bool
Returns true
if the table exists, otherwise false
.
// Checking table existence
if ($reflection->hasTable('users')) {
echo "The 'users' table exists";
}
getTable(string $name): Nette\Database\Reflection\Table
Returns the Nette\Database\Reflection\Table
object representing the given table. If the table does not exist, it
throws an exception Nette\Database\Exception\MissingTableException
.
// Retrieving a specific table
$table = $reflection->getTable('users');
Information about columns
The Nette\Database\Reflection\Table
object, obtained by calling getTable()
, allows you to retrieve detailed information about table columns.
getColumns(): Nette\Database\Reflection\Column[]
Returns an array of Nette\Database\Reflection\Column
objects representing the table columns.
getColumn(string $name): Nette\Database\Reflection\Column
Returns the Nette\Database\Reflection\Column object
representing the given column. If the column does not exist, it throws an exception
Nette\Database\Exception\MissingColumnException
.
The Column
object provides the following properties:
name
: The column name.nativeType
: The database-specific column data type.type
: The normalized column data type (see constantsNette\Utils\Type
).nullable
:true
if the column can containNULL
, otherwisefalse
.primary
:true
if the column is part of the primary key, otherwisefalse
.autoIncrement
:true
if the column is auto-increment, otherwisefalse
.default
: The column's default value, ornull
if not defined.vendor
: An array with additional database-specific information.
// Iterating through all columns in the 'users' table
$table = $reflection->getTable('users');
foreach ($table->getColumns() as $column) {
echo "Column: " . $column->name . "\n";
echo "Type: " . $column->nativeType . "\n";
echo "Allows NULL: " . ($column->nullable ? 'Yes' : 'No') . "\n";
echo "Default value: " . ($column->default ?? 'None') . "\n";
echo "Is primary key: " . ($column->primary ? 'Yes' : 'No') . "\n";
echo "Is auto-increment: " . ($column->autoIncrement ? 'Yes' : 'No') . "\n";
}
// Retrieving a specific column
$idColumn = $table->getColumn('id');
Indexes and primary keys
getIndexes(): Nette\Database\Reflection\Index[]
Returns an array of Nette\Database\Reflection\Index
objects representing the table indexes.
getIndex(string $name): Nette\Database\Reflection\Index
Returns the Nette\Database\Reflection\Index object
representing the given index. If the index does not exist, it throws an exception
Nette\Database\Exception\MissingIndexException
.
getPrimaryKey(): ?Nette\Database\Reflection\Index
Returns the Nette\Database\Reflection\Index
object representing the table's primary key, or null
if
the table has no primary key.
The Index
object provides the following properties:
name
: The name of the index.columns
: An array ofNette\Database\Reflection\Column
objects representing the columns that are part of the index.unique
:true
if the index is unique, otherwisefalse
.primary
:true
if the index is the primary key, otherwisefalse
.
$table = $reflection->getTable('users');
$printColumnNames = fn(array $columns) => implode(', ', array_map(fn($col) => $col->name, $columns));
// Listing all indexes
foreach ($table->getIndexes() as $index) {
echo "Index: " . ($index->name ?? 'Unnamed') . "\n";
echo "Columns: " . $printColumnNames($index->columns) . "\n";
echo "Is unique: " . ($index->unique ? 'Yes' : 'No') . "\n";
echo "Is primary key: " . ($index->primary ? 'Yes' : 'No') . "\n";
}
// Retrieving the primary key
if ($primaryKey = $table->getPrimaryKey()) {
echo "Primary key: " . $printColumnNames($primaryKey->columns) . "\n";
}
Foreign keys
getForeignKeys(): Nette\Database\Reflection\ForeignKey[]
Returns an array of Nette\Database\Reflection\ForeignKey
objects representing the table's foreign keys.
getForeignKey(string $name): Nette\Database\Reflection\ForeignKey
Returns the Nette\Database\Reflection\ForeignKey
object representing the given foreign key. If the foreign key does not exist, it throws an exception
Nette\Database\Exception\MissingForeignKeyException
.
The ForeignKey
object provides the following properties:
name
: The name of the foreign key.localColumns
: An array ofNette\Database\Reflection\Column
objects representing the local columns that make up the foreign key.foreignTable
: ANette\Database\Reflection\Table
object representing the foreign table that the foreign key references.foreignColumns
: An array ofNette\Database\Reflection\Column
objects representing the foreign columns the foreign key references.
$table = $reflection->getTable('books');
$printColumnNames = fn(array $columns) => implode(', ', array_map(fn($col) => $col->name, $columns));
foreach ($table->getForeignKeys() as $fk) {
echo "Foreign key: " . ($fk->name ?? 'Unnamed') . "\n";
echo "Local columns: " . $printColumnNames($fk->localColumns) . "\n";
echo "References table: {$fk->foreignTable->name}\n";
echo "References columns: " . $printColumnNames($fk->foreignColumns) . "\n";
}