woodholly/atk4-migrations
Composer 安装命令:
composer require woodholly/atk4-migrations
包简介
Database migrations for ATK4 Data using Doctrine Migrations
README 文档
README
Database migrations for ATK4 Data using Doctrine Migrations.
Table of Contents
- Overview
- Features
- Installation
- Indexes and Foreign Keys
- Quick Start
- Available Commands
- Table Renaming
- Fixing Mistakes
- Advanced
- Configuration
- Requirements
- Testing
Overview
Automatic database migrations for ATK4 Data using Doctrine Migrations. Define your schema in ATK4 Models, generate migrations automatically.
Works with any database state: Empty, existing, or production databases. The tool compares your models with the current database and generates only the necessary changes (CREATE, ALTER, or nothing if already in sync).
Features
- Automatic Schema Detection - Compares models with database, generates only necessary changes
- Full Rollback Support - Reverse any migration
- Zero Schema Duplication - Schema defined once in ATK4 Models
- Production Ready - Built on Doctrine Migrations
- Multi-Database - MySQL, PostgreSQL, SQLite, Oracle, SQL Server
- Declarative Constraints - Define indexes and foreign keys in models (extended Model class)
Installation
composer require woodholly/atk4-migrations
Indexes and Foreign Keys
ATK4 Data lacks declarative index/FK support. This package provides Atk4\Migrations\Model - an extended Model class that adds:
- Field options:
'index' => true,'unique' => trueinaddField() - Relationship options:
'onDelete','onUpdate','index','unique'inhasOne() - Methods:
addIndex(),addForeignKey(),getIndexes(),getForeignKeys()
Usage: Replace use Atk4\Data\Model → use Atk4\Migrations\Model
Note: Standard
Atk4\Data\Modelworks with migrations, but requires manual index/FK editing in each migration file.Atk4\Migrations\Modeldefines constraints declaratively. We hope this will be added to ATK4 Data core eventually.
Example:
use Atk4\Migrations\Model; class Post extends Model { public $table = 'post'; protected function init(): void { parent::init(); // Indexes $this->addField('title', ['index' => true]); // Regular index $this->addField('slug', ['unique' => true]); // Unique index $this->addIndex(['title', 'slug']); // Composite index // Foreign keys (CASCADE, RESTRICT, SET NULL, NO ACTION, SET DEFAULT) $this->hasOne('user_id', [ 'model' => [User::class], 'onDelete' => 'CASCADE', 'index' => true, // FK + index ]); // Composite foreign key $this->addForeignKey(['product_id', 'warehouse_id'], [ 'foreignTable' => 'inventory', 'foreignColumns' => ['product_id', 'warehouse_id'], 'onDelete' => 'RESTRICT', ]); } }
Quick Start
1. Create Configuration
Create migrations.php in project root (or config/migrations.php for better organization):
<?php use Atk4\Data\Persistence; return [ // Database connection 'persistence' => function () { return new Persistence\Sql('mysql://user:pass@localhost/dbname'); }, // List of Model classes to track 'models' => [ \App\Model\User::class, \App\Model\Post::class, \App\Model\Comment::class, ], // Where to store migration files (namespace => directory) 'migrations_paths' => [ 'Database\\Migrations' => 'migrations', // Class namespace => filesystem path ], ];
2. Generate & Run Migrations
# Generate migration from model changes vendor/bin/migrations-cli.php diff # Preview SQL (always check first!) vendor/bin/migrations-cli.php migrate --dry-run -vv # Execute migration vendor/bin/migrations-cli.php migrate
Use --configuration=config/migrations.php if config not in project root.
Available Commands
# Schema & Migration Generation vendor/bin/migrations-cli.php diff # Generate migration from schema diff vendor/bin/migrations-cli.php generate # Generate blank migration file vendor/bin/migrations-cli.php dump-schema # Dump current database schema to SQL file # Execution vendor/bin/migrations-cli.php migrate # Execute pending migrations vendor/bin/migrations-cli.php migrate prev # Rollback one migration vendor/bin/migrations-cli.php migrate --dry-run -vv # Preview SQL without executing vendor/bin/migrations-cli.php execute <version> --up # Execute specific migration vendor/bin/migrations-cli.php execute <version> --down # Rollback specific migration # Status & Information vendor/bin/migrations-cli.php status # Show migration status vendor/bin/migrations-cli.php list # List available migrations vendor/bin/migrations-cli.php up-to-date # Check if schema is up to date vendor/bin/migrations-cli.php latest # Show latest version # Advanced vendor/bin/migrations-cli.php version <version> --add # Mark as executed (without running) vendor/bin/migrations-cli.php version <version> --delete # Mark as not-executed (without running) vendor/bin/migrations-cli.php rollup # Squash all migrations into one vendor/bin/migrations-cli.php sync-metadata # Sync metadata storage
Note on dump-schema: This command dumps the current database schema (based on your models) to a SQL file. Useful for debugging schema differences or generating a full schema snapshot. The migrations directory should be empty or the schema reflects what would be created.
Table Renaming
Schema diff tools cannot distinguish table renames from drop+create operations. Changing public $table = 'old_name' to public $table = 'new_name' generates DROP + CREATE, deleting all data.
Workflow:
# 1. Change table name in model # 2. Generate migration vendor/bin/migrations-cli.php diff # 3. Preview - will show DROP+CREATE vendor/bin/migrations-cli.php migrate --dry-run -vv # 4. Manually edit migration file to use renameTable()
// migrations/Version20250116120000.php public function up(Schema $schema): void { // $this->addSql('DROP TABLE old_users'); // $this->addSql('CREATE TABLE users (...)'); $schema->renameTable('old_users', 'users'); } public function down(Schema $schema): void { $schema->renameTable('users', 'old_users'); }
# 5. Verify and execute
vendor/bin/migrations-cli.php migrate --dry-run -vv
vendor/bin/migrations-cli.php migrate
Renaming + modifying fields: Either create two separate migrations (rename first, then modify), or manually edit the migration to rename then ALTER using the new table name.
Fixing Mistakes
Migration not executed yet? Just delete the file:
rm migrations/Version20250116120000.php
Migration already executed? Use version command to unmark it:
# Option 1: Mark as not-executed (without running rollback SQL) vendor/bin/migrations-cli.php version Version20250116120000 --delete rm migrations/Version20250116120000.php # Option 2: Actually rollback the database changes vendor/bin/migrations-cli.php migrate prev # Rollback SQL is executed rm migrations/Version20250116120000.php
Note: Use --delete when the migration didn't actually change anything or when you've manually reverted the changes. Use migrate prev when you want to actually reverse the database changes.
Wrong model definition? Fix the model and generate a new corrective migration:
# Fix the error in your model # Then generate a new migration that will fix the database vendor/bin/migrations-cli.php diff vendor/bin/migrations-cli.php migrate --dry-run -vv # Verify it fixes the issue vendor/bin/migrations-cli.php migrate
Advanced
Manual Migration Editing
For advanced cases, manually edit generated migration files using Doctrine's Schema API. See Doctrine Migrations documentation for available methods.
Auto-Discovery
You can automatically discover models from a directory instead of listing them manually:
<?php declare(strict_types=1); use Atk4\Data\Persistence; // Helper function to discover models from src/Model directory function discoverModels(string $directory, string $namespace): array { $models = []; $files = glob($directory . '/*.php'); foreach ($files as $file) { $className = $namespace . '\\' . basename($file, '.php'); // Try to load the file first if (!class_exists($className)) { require_once $file; } if (class_exists($className)) { $models[] = $className; } } return $models; } // Load autoloader require_once __DIR__ . '/vendor/autoload.php'; return [ 'persistence' => function () { return new Persistence\Sql('mysql://user:pass@localhost/dbname'); }, 'models' => discoverModels(__DIR__ . '/src/Model', 'App\\Model'), 'migrations_paths' => [ 'Database\\Migrations' => 'migrations', ], ];
This auto-discovery approach requires files in src/Model/*.php with class names matching filenames.
Configuration
All available options:
<?php use Atk4\Data\Persistence; return [ // Required: Database connection 'persistence' => function () { return new Persistence\Sql('mysql://user:pass@localhost/dbname'); }, // Required: Models to track 'models' => [ \App\Model\User::class, \App\Model\Post::class, ], // Optional: Migration history tracking table (defaults shown) 'table_storage' => [ 'table_name' => 'doctrine_migration_versions', // Table that tracks executed migrations 'version_column_name' => 'version', // Column storing migration version numbers ], // Optional: Where migrations are stored (namespace => directory path) // Key = PHP namespace for migration classes // Value = filesystem directory where migration files are created 'migrations_paths' => [ 'Database\\Migrations' => 'migrations', ], // Optional: Wrap all migrations in transaction 'all_or_nothing' => true, // Optional: Each migration in its own transaction 'transactional' => true, ];
Understanding table_storage
The table_storage option configures where Doctrine Migrations tracks migration execution history:
What it does:
- Creates a table in your database (default:
doctrine_migration_versions) - Stores a record each time a migration is executed
- Allows the system to know which migrations have already been applied
Example table contents:
doctrine_migration_versions
+---------------------------+---------------------+
| version | executed_at |
+---------------------------+---------------------+
| Tests\Version20250116001 | 2025-01-16 10:00:00 |
| Tests\Version20250116002 | 2025-01-16 10:05:00 |
+---------------------------+---------------------+
When to customize:
- If you already have a table named
doctrine_migration_versions(avoid conflicts) - If your project has naming conventions for system tables
- If you're integrating with an existing migration system
Default values are fine for most projects - you only need to specify table_storage if you want to change the defaults.
How It Works
Your ATK4 Models
↓
Atk4SchemaProvider (implements Doctrine SchemaProviderInterface)
↓
Doctrine Comparator (compares with current DB)
↓
Generated Migration File
↓
Doctrine Migrations (runs/tracks/rollbacks)
The package extracts Doctrine Table objects from ATK4's Migrator class (which already builds them internally), then uses Doctrine's built-in schema comparison to generate migrations.
Requirements
- PHP 7.4 or higher
atk4/data ^6.0doctrine/migrations ^3.5symfony/console ^5.0 || ^6.0 || ^7.0
Testing
vendor/bin/phpunit
License
MIT
Credits
Built on top of:
woodholly/atk4-migrations 适用场景与选型建议
woodholly/atk4-migrations 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 11 月 23 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「database」 「migrations」 「schema」 「doctrine」 「atk4」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 woodholly/atk4-migrations 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 woodholly/atk4-migrations 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 woodholly/atk4-migrations 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dibi is Database Abstraction Library for PHP
Store your language lines in the database, yaml or other sources
Extension for Opis JSON Schema
Symfony ClickhouseMigrationsBundle
Very simple SQL-based database migrations tool - a heavily stripped down fork of robmorgan/phinx
A package for automatically encrypting and decrypting Eloquent attributes in Laravel 5.5+, based on configuration settings.
统计信息
- 总下载量: 1
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 18
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-23