{"id":51237663,"url":"https://github.com/erilshackle/php-schema-engine","last_synced_at":"2026-06-28T22:00:39.151Z","repository":{"id":359751952,"uuid":"1247383658","full_name":"erilshackle/php-schema-engine","owner":"erilshackle","description":"A schema-first migration engine for PHP with DSL, introspection, diffing and automatic SQL generation.. What if I use prisma ideia in fluent php?","archived":false,"fork":false,"pushed_at":"2026-06-20T02:28:11.000Z","size":149,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T20:05:41.726Z","etag":null,"topics":["code-generation","database","database-migrations","database-schema","dsl","migration-tool","mysql","php","schema","schema-builder","schema-migrations"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erilshackle.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"Roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T08:35:08.000Z","updated_at":"2026-06-20T02:28:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/erilshackle/php-schema-engine","commit_stats":null,"previous_names":["erilshackle/php-schema-engine"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/erilshackle/php-schema-engine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erilshackle%2Fphp-schema-engine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erilshackle%2Fphp-schema-engine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erilshackle%2Fphp-schema-engine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erilshackle%2Fphp-schema-engine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erilshackle","download_url":"https://codeload.github.com/erilshackle/php-schema-engine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erilshackle%2Fphp-schema-engine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34905180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-generation","database","database-migrations","database-schema","dsl","migration-tool","mysql","php","schema","schema-builder","schema-migrations"],"created_at":"2026-06-28T22:00:26.389Z","updated_at":"2026-06-28T22:00:39.146Z","avatar_url":"https://github.com/erilshackle.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PHP Schema Engine\n\nA modern schema-first migration engine for PHP.\n\nPHP Schema Engine lets you define your database structure using a clean PHP DSL, compare it against the current database schema, generate SQL automatically, and apply changes through a lightweight CLI.\n\n\u003e Current version: `0.3.0`\n\n![PHP](https://img.shields.io/badge/PHP-8.2%2B-blue)\n![Tests](https://github.com/erilshackle/php-schema-engine/actions/workflows/tests.yml/badge.svg)\n![License](https://img.shields.io/badge/license-MIT-green)\n\n---\n\n## Features\n\n- Schema-first database definition\n- Fluent PHP DSL\n- MySQL/MariaDB support\n- Automatic schema introspection\n- Table and column diffing\n- Partial index diffing\n- SQL generation\n- Migration execution\n- Migration history\n- Model generation\n- Dry-run mode\n- Destructive operation protection\n- Database reset support\n- Snapshot generation\n- Foreign key support\n- Debug trace mode\n\n---\n\n## Installation\n\n```bash\ncomposer require eril/schema-engine\n```\n\n---\n\n## Initialization\n\nGenerate the default configuration file:\n\n```bash\nphp bin/migrate --init\n```\n\nThis creates:\n\n```txt\nschema-engine.php\ndatabase/schema.php\ndatabase/bootstrap.sql\ndatabase/snapshots/\n```\n\n---\n\n## Configuration\n\nGenerated config example:\n\n```php\n\u003c?php\n\nreturn [\n\n    // Schema file path\n    'schema' =\u003e 'database/schema.php',\n\n    'bootstrap' =\u003e 'bootstrap.php',\n\n    // Database connection configuration\n    'database' =\u003e [\n        'driver' =\u003e 'mysql',\n        'host' =\u003e $_ENV['DB_HOST'] ?? '127.0.0.1',\n        'port' =\u003e $_ENV['DB_PORT'] ?? 3306,\n        'database' =\u003e $_ENV['DB_NAME'] ?? 'app',\n        'username' =\u003e $_ENV['DB_USER'] ?? 'root',\n        'password' =\u003e $_ENV['DB_PASS'] ?? '',\n    ],\n\n    // Model generator setup\n    'generator' =\u003e [\n        'models' =\u003e [\n            'enabled' =\u003e false,\n            'namespace' =\u003e 'App\\\\Models',\n            'path' =\u003e '/app/Models',\n            'extends' =\u003e null,\n        ],\n    ],\n];\n```\n\nOptional bootstrap file:\n\n```txt\nbootstrap.php\n```\n\nUseful for:\n\n* loading `.env`\n* bootstrapping frameworks\n* loading helpers\n* custom runtime setup\n\n---\n\n## Basic Usage\n\nCreate a schema file:\n\n```php\n\u003c?php\n\nuse SchemaEngine\\DSL\\Schema;\nuse SchemaEngine\\DSL\\Table;\n\nreturn function (Schema $schema) {\n\n    $schema-\u003etable('users', function (Table $t) {\n\n        $t-\u003eid();\n\n        $t-\u003estring('name');\n\n        $t-\u003estring('email')\n            -\u003eunique();\n\n        $t-\u003etimestamps();\n    });\n\n};\n```\n\nRun a dry-run first:\n\n```bash\nphp bin/migrate --dry-run\n```\n\nApply the migration:\n\n```bash\nphp bin/migrate --yes\n```\n\n---\n\n## Defining Tables\n\n```php\n$schema-\u003etable('users', function ($t) {\n\n    $t-\u003eid();\n\n    $t-\u003estring('name');\n\n    $t-\u003estring('email')\n        -\u003eunique();\n\n    $t-\u003eint('age')\n        -\u003edefault(0);\n\n    $t-\u003etimestamps();\n});\n```\n\n---\n\n## Column Types\n\n```php\n$t-\u003eid();\n\n$t-\u003estring('name');\n\n$t-\u003echar('code', 2);\n\n$t-\u003etext('body');\n\n$t-\u003elongText('content');\n\n$t-\u003eint('age');\n\n$t-\u003ebigInt('views');\n\n$t-\u003efloat('rating');\n\n$t-\u003edouble('score');\n\n$t-\u003edecimal('price', 10, 2);\n\n$t-\u003eboolean('active');\n\n$t-\u003edatetime('published_at');\n\n$t-\u003etimestamp('created_at');\n\n$t-\u003ejson('meta');\n\n$t-\u003euuid('uuid');\n```\n\n---\n\n## Column Modifiers\n\n```php\n$t-\u003estring('email')\n    -\u003eunique();\n\n$t-\u003estring('slug')\n    -\u003eindex();\n\n$t-\u003estring('name')\n    -\u003enullable();\n\n$t-\u003eint('age')\n    -\u003edefault(0);\n\n$t-\u003etimestamp('created_at')\n    -\u003edefaultCurrentTimestamp();\n\n$t-\u003etimestamp('updated_at')\n    -\u003edefaultRaw('CURRENT_TIMESTAMP');\n```\n\n---\n\n## Shortcuts\n\n```php\n$t-\u003eid();\n\n$t-\u003etimestamps();\n\n$t-\u003ecreatedAt();\n\n$t-\u003eupdatedAt();\n\n$t-\u003esoftDeletes();\n\n$t-\u003erememberToken();\n```\n\n---\n\n## Indexes\n\nSingle-column indexes:\n\n```php\n$t-\u003estring('email')\n    -\u003eunique();\n\n$t-\u003estring('slug')\n    -\u003eindex();\n```\n\nComposite indexes:\n\n```php\n$t-\u003eunique(['email', 'tenant_id']);\n\n$t-\u003eindex(['first_name', 'last_name']);\n```\n\nIndexes are automatically introspected and partially diffed.\n\nCurrent V1 behavior:\n\n* missing indexes are automatically added\n* removed indexes are automatically dropped\n* changed indexes are ignored intentionally with warnings\n\nExample warning:\n\n```txt\nIndex 'email_unique' on table 'users' differs from desired schema and was ignored.\n```\n\n---\n\n## Foreign Keys\n\nSimple inferred relation:\n\n```php\n$t-\u003eforeign('user_id');\n```\n\nExplicit references:\n\n```php\n$t-\u003eforeign('user_id')\n    -\u003econstrained() // or references('users')\n    -\u003ecascadeOnDelete();\n```\n\nExplicit references:\n\n```php\n$t-\u003eforeign('user_id')\n    -\u003econstrained() // or references('users')\n    -\u003ecascadeOnDelete();\n```\n\nou:\n\n```php\n$t-\u003eforeign('author_id')\n    -\u003ereferences('users');\n```\n\nCustom referenced column:\n\n```php\n$t-\u003euuid('author_id')\n    -\u003ereferences('users', 'uuid');\n```\n\nAvailable relation actions:\n\n```php\n-\u003ecascadeOnDelete()\n\n-\u003ecascadeOnUpdate()\n\n-\u003erestrictOnDelete()\n\n-\u003erestrictOnUpdate()\n\n-\u003enullOnDelete()\n\n-\u003enullOnUpdate()\n```\n\n\u003e In V1, foreign keys are generated when creating new tables only. Foreign key changes after table creation are not automatically migrated yet.\n\n---\n\n## Model Generation\n\nGenerate models from your schema:\n\n```bash\nphp bin/migrate --generate-models\n```\n\nExample generated model:\n\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nclass User\n{\n    protected string $table = 'users';\n}\n```\n\nGenerator configuration:\n\n```php\n'generator' =\u003e [\n    'models' =\u003e [\n        'enabled' =\u003e true,\n        'namespace' =\u003e 'App\\\\Models',\n        'path' =\u003e '/app/Models',\n        'extends' =\u003e 'App\\\\Core\\\\Model',\n    ],\n],\n```\n\n---\n\n## CLI\n\n| Command             | Description                           |\n| ------------------- | ------------------------------------- |\n| `--init`            | Initialize a new project              |\n| `--yes`             | Don't ask for confirmation            |\n| `--dry-run`         | Preview pending changes               |\n| `--force`           | Execute dangerous SQL like delete     |\n| `--status`          | Show migration history                |\n| `--sql`             | Export SQL for pending schema changes |\n| `--schema-sql`      | Export SQL for the entire schema      |\n| `--rollback`        | Rollback the latest batch             |\n| `--fresh`           | Drop all tables                       |\n| `--clear-history`   | Clear histries                        |\n| `--generate-models` | Generate model classes                |\n\nDry-run:\n\n```bash\nphp bin/migrate --dry-run\n```\n\nApply migrations without confirmation:\n\n```bash\nphp bin/migrate --yes\n```\n\nAllow destructive operations:\n\n```bash\nphp bin/migrate --force\n```\n\nShow migration history:\n\n```bash\nphp bin/migrate --status\n```\n\nReset database:\n\n```bash\nphp bin/migrate --fresh --force --yes\n```\n\nReset database and clear history:\n\n```bash\nphp bin/migrate --fresh --force --yes --clear-history\n```\n\nGenerate models:\n\n```bash\nphp bin/migrate --generate-models\n```\n\nShow stack trace on exceptions:\n\n```bash\nphp bin/migrate --trace\n```\n\n---\n\n## Migration History\n\nExecuted operations are stored in:\n\n```txt\nschema_migrations\n```\n\nThis table is managed internally by the engine and ignored during schema diffing.\n\n---\n\n## Exporting SQL\n\nPHP Schema Engine can generate SQL without executing migrations.\n\n### Export migration SQL (diff)\n\nGenerate the SQL required to migrate the current database schema:\n\n```bash\nphp bin/migrate --sql\n```\n\nExample:\n\n```sql\nALTER TABLE users\nADD COLUMN phone VARCHAR(20);\n\nCREATE TABLE posts (...);\n```\n\nThis command uses schema introspection and the diff engine.\n\n---\n\n### Export full schema SQL\n\nGenerate SQL for the entire schema definition:\n\n```bash\nphp bin/migrate --schema-sql\n```\n\nExample:\n\n```sql\nCREATE TABLE users (...);\n\nCREATE TABLE posts (...);\n```\n\nThis command ignores the current database and generates SQL directly from `database/schema.php`.\n\n---\n\n### Save SQL to a file\n\n```bash\nbin/migrate --schema-sql \u003e install.sql\n```\n\nor\n\n```bash\nbin/migrate --sql \u003e migration.sql\n```\n\n$ notice not to use  **php** because __\u003e__ stdout is not a tty\n\nThis is useful for:\n\n* Manual deployments\n* Database reviews\n* Backup scripts\n* Installation packages\n* CI/CD pipelines\n\n\n## Safety\n\nBy default, destructive operations are blocked.\n\nThis includes:\n\n* dropping tables\n* dropping columns\n* dropping indexes\n\nTo allow destructive operations:\n\n```bash\nphp bin/migrate --force\n```\n\n---\n\n## Debugging\n\nEnable stack traces during execution:\n\n```bash\nphp bin/migrate --trace\n```\n\nExample output:\n\n```txt\n[ERROR] Table users already exists\nFile: .../Migrator.php:62\n\nStack trace:\n\n#0 .../Migrator.php:62 run()\n#1 .../MigrateCommand.php:88 printPlannedSql()\n#2 .../bin/migrate:24 run()\n```\n\n---\n\n## Current Limitations\n\nPHP Schema Engine `0.3.0` is intentionally conservative.\n\nCurrent V1 limitations:\n\n* MySQL/MariaDB only\n* Index diffing is partial and intentionally conservative\n* Existing indexes are not automatically modified\n* Foreign key changes after table creation are not automatically migrated\n* Rename detection is disabled by default\n* Table recreation is not implemented yet\n* No PostgreSQL grammar yet\n* No SQLite grammar yet\n* No ORM/query builder layer yet\n\n---\n\n## Philosophy\n\nPHP Schema Engine follows a schema-first approach.\n\nThe schema file is the source of truth.\n\n```txt\nSchema DSL\n    ↓\nSchema Metadata\n    ↓\nDatabase Introspection\n    ↓\nDiff Engine\n    ↓\nSQL Generation\n    ↓\nMigration Execution\n```\n\nThe DSL is designed to stay expressive, while the internal architecture keeps metadata, diffing, SQL generation, and execution separated.\n\n---\n\n## Roadmap\n\n### V0.1\n\n* Schema DSL\n* MySQL introspection\n* Column diffing\n* Partial index diffing\n* SQL generator\n* CLI\n* Migration history\n* Model generation\n* Foreign keys on create\n\n### V0.2\n\n* migrate:fresh\n* migrate:reset\n* better CLI output\n* schema snapshots\n\n### V0.3\n\n* foreign key diffing\n* rollback support\n\n  \n### V0.4\n\n* advanced index diffing\n* table recreation mode\n* explicit rename operations\n\n### V1.0\n\n* stable public API\n* stronger type system\n* advanced MySQL grammar\n* multi-driver foundation\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferilshackle%2Fphp-schema-engine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferilshackle%2Fphp-schema-engine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferilshackle%2Fphp-schema-engine/lists"}