Schema Management (Sculpt CLI)

Sculpt is ObjectQuel's command-line tool for database schema management. It generates entities, creates and applies migrations, and keeps your database schema in sync with your entity definitions.

Creating Entities

The make:entity command walks you through creating a new entity interactively. It prompts for a class name, table name, properties (with type, length, and nullability), and relationships. When finished it writes the entity file with all annotations in place.

$ php bin/sculpt make:entity

 Entity name: > Product
 Table name [products]: > products

 Property name: > price
 Property type [string]: > decimal
 Property precision [10,2]: > 10,2
 Can this property be null? [no]: > no

 Property name: >

 Relationship type (OneToMany, ManyToOne, OneToOne, or <return> to skip): > ManyToOne
 Related entity: > Category

 Success! Created: src/Entity/ProductEntity.php

The generated entity contains @Orm\Column annotations for each property, a primary key with @Orm\PrimaryKeyStrategy, and relationship annotations with the correct targetEntity and inversedBy values. Getters and setters are included for all properties.

Reverse Engineering

make:entity-from-table generates an entity from an existing database table. Sculpt reads the table's columns, types, and foreign keys, then produces a fully annotated entity. Foreign key columns become relationship properties; inverse sides are detected automatically from other tables that reference this one.

$ php bin/sculpt make:entity-from-table

 Available tables: categories, products, users, orders, order_items

 Select table: > products
 Entity name [ProductEntity]: > ProductEntity
 Namespace [App\Entity]: > App\Entity
 Generate relationships? [yes]: > yes

 Success! Created: src/Entity/ProductEntity.php
 Detected: ManyToOne category_id -> CategoryEntity
 Detected: OneToMany referenced by OrderItemEntity.product_id

This is the fastest way to bring ObjectQuel into an existing project. Run the command once per table, then adjust any annotations the wizard could not infer automatically.

Migrations

make:migrations diffs your entity annotations against the live database schema and generates a migration file covering every detected change — new tables, altered columns, added or removed indexes, and dropped columns.

$ php bin/sculpt make:migrations

 Changes detected:
 ✓ New table: products
 ✓ New index: products.idx_category_id
 ✓ Modified column: users.email (added unique constraint)
 ✓ Dropped column: orders.legacy_status

 Success! Created: database/migrations/20250603145623_EntitySchemaMigration.php

The generated file contains both up() and down() methods. Review it before applying — particularly column drops, which cannot be recovered from without a backup.

Applying migrations

# Preview what would run without touching the database
$ php bin/sculpt quel:migrate --dry-run

# Apply all pending migrations
$ php bin/sculpt quel:migrate

# Check which migrations have run
$ php bin/sculpt quel:migrate --status

Rolling back

# Rollback the last migration
$ php bin/sculpt quel:migrate --rollback

# Rollback multiple steps
$ php bin/sculpt quel:migrate --rollback --steps=3

Always take a database backup before applying migrations in production. --rollback executes the down() method of the migration, but if the down() method drops a table, rolling back does not recover the data.

Index Visibility

Dropping an index is permanent. quel:index-hide offers a safer alternative: it marks the index as invisible to the query optimizer while the engine continues maintaining it. If queries slow down, quel:index-show restores visibility instantly with no data loss.

# Hide an index
$ php bin/sculpt quel:index-hide User idx_email

# Restore it
$ php bin/sculpt quel:index-show User idx_email

Both commands accept an entity name rather than a raw table name. The entity is resolved to its owning table via the ObjectQuel metadata store. If either argument is omitted, the command prompts interactively.

Safe index removal workflow

# 1. Hide the index
$ php bin/sculpt quel:index-hide OrderLine idx_created_at

# 2. Run the application under realistic load; inspect slow query logs

# 3a. No regressions? Remove the @Orm\Index annotation and drop permanently:
$ php bin/sculpt make:migrations
$ php bin/sculpt quel:migrate

# 3b. Regressions? Restore in one command:
$ php bin/sculpt quel:index-show OrderLine idx_created_at

Database support

Database Minimum version Hide syntax Show syntax
MySQL 8.0.0 INVISIBLE VISIBLE
MariaDB any IGNORED NOT IGNORED
PostgreSQL Not supported

Both commands perform a version check on connection and exit with a descriptive error if the requirement is not met.