ascetic-soft/rowcast-schema
Composer 安装命令:
composer require ascetic-soft/rowcast-schema
包简介
Schema-first migration tool for PDO databases, friendly to Rowcast
README 文档
README
Schema-first migration toolkit for PDO databases (PHP 8.4+).
Zero external dependencies. Describe your database structure in a PHP file, diff it against a live database, and generate reversible PHP migrations automatically. Designed to work alongside Rowcast.
Documentation: English | Русский
Requirements
- PHP >= 8.4
- PDO extension
Installation
composer require ascetic-soft/rowcast-schema
Optional YAML schema support:
composer require symfony/yaml
Quick Start
1. Create a configuration file
Create rowcast-schema.php in your project root (default path):
<?php return [ 'connection' => [ 'dsn' => 'mysql:host=localhost;dbname=app', 'username' => 'root', 'password' => 'secret', ], 'schema' => __DIR__ . '/schema.php', 'migrations' => __DIR__ . '/migrations', 'migration_table' => '_rowcast_migrations', 'ignore_tables' => [ '/^tmp_/', '/^audit_/', static fn (string $table): bool => str_ends_with($table, '_shadow'), ], ];
You can also store config in a custom location and pass it via CLI:
vendor/bin/rowcast-schema --config=database/rowcast-schema.php diff
Config may return either an array or a factory Closure(string $projectDir): array.
Factory mode is useful for loading environment variables from your app kernel/project root.
migration_table defines the table used to track applied migrations.
This table is always ignored automatically in schema diff.
Use ignore_tables to add custom ignore rules: regex strings and/or callbacks.
2. Define a schema
schema.php:
<?php return [ 'tables' => [ 'users' => [ 'columns' => [ 'id' => ['type' => 'integer', 'primaryKey' => true, 'autoIncrement' => true], 'email' => ['type' => 'string', 'length' => 255], 'status' => ['type' => 'enum', 'values' => ['active', 'banned']], 'created_at' => ['type' => 'datetime', 'default' => 'CURRENT_TIMESTAMP'], ], 'indexes' => [ 'idx_users_email' => ['columns' => ['email'], 'unique' => true], ], ], ], ];
3. Generate and apply a migration
# Generate a migration from schema diff vendor/bin/rowcast-schema diff # Generate an empty migration file vendor/bin/rowcast-schema make # Apply pending migrations vendor/bin/rowcast-schema migrate # Check sync status vendor/bin/rowcast-schema status
Global CLI option:
--config=path(or--config path) — use a custom configuration file path.
Schema Definition
Supported formats
| Format | File | Dependency |
|---|---|---|
| PHP array (default) | schema.php |
None |
| YAML | schema.yaml / schema.yml |
symfony/yaml |
| PHP attributes | directory (e.g. src/Entity) |
None |
The format is detected automatically by schema path:
- if
schemais a directory, attribute parser is used - if
schemais a file, parser is selected by extension (.php,.yaml,.yml)
Attribute-based schema
You can define schema directly in PHP classes via attributes.
rowcast-schema.php:
<?php return [ 'connection' => [ 'dsn' => 'mysql:host=localhost;dbname=app', 'username' => 'root', 'password' => 'secret', ], 'schema' => __DIR__ . '/src/Entity', 'migrations' => __DIR__ . '/migrations', ];
Entity example:
<?php use AsceticSoft\RowcastSchema\Attribute\Column; use AsceticSoft\RowcastSchema\Attribute\ForeignKey; use AsceticSoft\RowcastSchema\Attribute\Index; use AsceticSoft\RowcastSchema\Attribute\Table; enum UserStatus: string { case Active = 'active'; case Banned = 'banned'; } #[Table] // User -> users #[Index('idx_users_email', columns: ['email'], unique: true)] final class User { #[Column(primaryKey: true, autoIncrement: true)] public int $id; #[Column(length: 255)] public string $email; #[Column] public UserStatus $status; // BackedEnum(string) -> type=enum, values from enum cases } #[Table('blog_posts')] final class Post { #[Column(primaryKey: true, autoIncrement: true)] public int $id; #[Column] #[ForeignKey('fk_posts_user', referenceTable: 'users', referenceColumns: ['id'], onDelete: 'CASCADE')] public int $userId; }
Type inference for attribute columns:
- property type mapping:
int,string,bool,float,array,DateTimeInterface BackedEnum(string) ->enum+ automaticvaluesBackedEnum(int) ->integer- override is still possible via
#[Column(type: ...)] - if
#[Column(default: ...)]is omitted and a property has a class default (e.g.public bool $published = false;), that value is used as the DB default - when both are present,
#[Column(default: ...)]has priority over the property default
Abstract column types
integer, smallint, bigint, string, text, boolean, decimal, float, double, datetime, date, time, timestamp, timestamptz, uuid, json, binary, enum
Custom database types (pgvector/citext/etc.)
Schema files may also use raw database type strings in type.
Unknown types are preserved as custom databaseType and emitted to SQL as-is.
return [ 'tables' => [ 'embeddings' => [ 'columns' => [ 'id' => ['type' => 'bigint', 'primaryKey' => true, 'autoIncrement' => true], 'gigachat_vector' => ['type' => 'vector(1536)', 'nullable' => true], 'title_ci' => ['type' => 'citext'], ], ], ], ];
This works for extension types such as vector (pgvector), citext, PostGIS types, and other vendor-specific types.
Column properties
| Property | Default | Description |
|---|---|---|
type |
(required) | Abstract column type |
nullable |
false |
Allow NULL values |
default |
— | Default value |
primaryKey |
false |
Mark as primary key |
autoIncrement |
false |
Auto-increment |
length |
— | String/binary length |
precision / scale |
— | Decimal precision |
unsigned |
false |
Unsigned integer |
comment |
— | Column comment |
values |
— | Enum values list |
For type: string, default length is 255 when length is omitted.
Migration Builder API
Generated migrations and manual migration code use a unified column API:
$table->column('id', 'integer')->primaryKey(); $table->column('email', 'string'); // VARCHAR(255) by default $table->column('status', ColumnType::String)->length(50); $table->column('payload', 'jsonb'); // custom raw DB type
To execute arbitrary SQL inside a migration:
public function up(SchemaBuilder $schema): void { $schema->sql("UPDATE users SET status = 'active' WHERE status IS NULL"); }
column() accepts:
ColumnTypeenum values (ColumnType::String,ColumnType::Datetime, ...)- known abstract type strings (
'string','integer', ...) - any custom database type string (
'jsonb','citext','numeric(20,6)', ...)
Foreign keys
'foreignKeys' => [ 'fk_posts_user' => [ 'columns' => ['user_id'], 'referenceTable' => 'users', 'referenceColumns' => ['id'], 'onDelete' => 'CASCADE', 'onUpdate' => 'SET NULL', ], ],
CLI Commands
vendor/bin/rowcast-schema <command> [options]
| Command | Description |
|---|---|
diff |
Generate a migration from schema changes |
diff --dry-run |
Preview operations without generating a file |
make |
Generate an empty migration file |
migrate |
Apply all pending migrations |
rollback |
Rollback the latest migration |
rollback --step=N |
Rollback the last N migrations |
status |
Show migration state and schema sync status |
How It Works
- Parse — reads schema file (
.php/.yaml) or scans attribute directory and builds an internalSchemamodel. - Introspect — reads the current database structure via PDO.
- Diff —
SchemaDiffercomputes a list of operations (create, drop, add, alter, etc.). - Generate — creates a PHP migration class with
up()anddown()methods. - Execute —
MigrationRunnerapplies operations through a database-specific SQL platform. - Track — applied versions are stored in the
_rowcast_migrationstable.
SQLite Support
SQLite has limited DDL capabilities (ALTER TABLE, foreign keys). For unsupported operations, Rowcast Schema uses a rebuild pipeline:
- Create a temporary table with the new structure
- Copy data from the original table
- Drop the original and rename the temporary table
- Recreate indexes and foreign keys
This enables complex schema changes on SQLite transparently.
Architecture
AsceticSoft\RowcastSchema\
├── Attribute\
│ ├── Table, Column # Entity/table and property/column metadata
│ └── Index, ForeignKey # Index and FK metadata
├── Schema\
│ ├── Schema # Root schema model
│ ├── Table, Column, Index, ForeignKey # Schema components
│ └── ColumnType # Abstract type enum
├── Parser\
│ ├── SchemaParserInterface # Parser contract
│ ├── PhpSchemaParser # PHP array parser (default)
│ ├── YamlSchemaParser # YAML parser (optional)
│ ├── AttributeSchemaParser # Attribute directory parser
│ ├── ArraySchemaBuilder # Shared array → Schema builder
│ ├── AttributeSchemaBuilder # Reflection attributes → Schema builder
│ ├── ClassScanner # Directory PHP class scanner
│ └── NamingStrategy # class/property -> table/column naming
├── Introspector\
│ ├── IntrospectorInterface # Introspector contract
│ ├── IntrospectorFactory # PDO driver → introspector
│ ├── MysqlIntrospector # MySQL introspection
│ ├── PostgresIntrospector # PostgreSQL introspection
│ └── SqliteIntrospector # SQLite introspection
├── Diff\
│ ├── SchemaDiffer # Schema comparison engine
│ └── Operation\
│ ├── OperationInterface # Operation contract
│ ├── CreateTable, DropTable # Table-level operations
│ ├── AddColumn, AlterColumn, DropColumn
│ ├── AddIndex, DropIndex
│ └── AddForeignKey, DropForeignKey
├── Platform\
│ ├── PlatformInterface # SQL generation contract
│ ├── PlatformFactory # PDO driver → platform
│ ├── AbstractPlatform # Shared SQL logic
│ ├── MysqlPlatform # MySQL DDL
│ ├── PostgresPlatform # PostgreSQL DDL
│ └── SqlitePlatform # SQLite DDL (with rebuild)
├── Migration\
│ ├── MigrationInterface # Migration contract
│ ├── AbstractMigration # Base migration class
│ ├── MigrationGenerator # PHP migration file generator
│ ├── MigrationLoader # Loads migration files from disk
│ ├── MigrationRunner # Applies/rollbacks migrations
│ ├── MigrationRepositoryInterface # Repository contract
│ ├── DatabaseMigrationRepository # Tracks applied migrations in DB
│ └── SqliteTableRebuilder # SQLite rebuild pipeline
├── SchemaBuilder\
│ ├── SchemaBuilder # Fluent API for migration operations
│ ├── TableBuilder # Fluent table/column definition
│ └── ColumnBuilder # Fluent column properties
├── TypeMapper\
│ ├── TypeMapperInterface # Type mapper contract
│ ├── MysqlTypeMapper # MySQL type mapping
│ ├── PostgresTypeMapper # PostgreSQL type mapping
│ └── SqliteTypeMapper # SQLite type mapping
├── Pdo\
│ └── PdoDriverResolver # Centralized PDO driver detection
└── Cli\
├── Application # CLI entry point
├── Config # Configuration loader
└── Command\
├── CommandInterface # Command contract
├── DiffCommand # diff command
├── MakeCommand # make command
├── MigrateCommand # migrate command
├── RollbackCommand # rollback command
└── StatusCommand # status command
Testing
composer install vendor/bin/phpunit
Static analysis:
vendor/bin/phpstan analyse
License
MIT
ascetic-soft/rowcast-schema 适用场景与选型建议
ascetic-soft/rowcast-schema 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 115 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 03 月 06 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「database」 「migrations」 「yaml」 「php」 「schema」 「pdo」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 ascetic-soft/rowcast-schema 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ascetic-soft/rowcast-schema 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 ascetic-soft/rowcast-schema 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Dibi is Database Abstraction Library for PHP
Store your language lines in the database, yaml or other sources
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.
Laravel table comments loader (part of Diplodocker project)
统计信息
- 总下载量: 115
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 32
- 依赖项目数: 1
- 推荐数: 1
其他信息
- 授权协议: MIT
- 更新时间: 2026-03-06