Red icon indicating copy to clipboard operation
Red copied to clipboard

Add schema.update method for intelligent schema migration

Open Copilot opened this issue 5 months ago • 2 comments

This PR adds a new update method to schema(...) objects that intelligently compares the current schema definition with the database state and applies necessary changes to make them match.

Problem

Previously, there was no way to automatically update database schemas when model definitions changed. Users had to manually manage schema migrations or recreate tables entirely:

schema(Account, Transaction).create;  # Works first time
# After changing model definitions, no easy way to update the database

Solution

Added a new update method to Red::Schema that provides intelligent schema migration:

schema(Account, Transaction).update;  # Compares schema with DB and applies changes
schema(Account, Transaction).update;  # Idempotent - safe to run multiple times

The method can also be chained like other schema methods:

schema(Account, Transaction).create.update;  # Method chaining supported

Implementation

The implementation leverages Red's existing schema comparison infrastructure:

  1. Added Red::Schema.update method that compares model definitions with database state using diff-from-db
  2. Uses existing diff-to-ast infrastructure to convert differences into executable AST nodes
  3. Executes changes in proper order to handle dependencies and constraints
  4. Runs in a transaction to ensure atomicity of schema changes
  5. Preserves existing data during schema updates

The solution reuses Red's robust schema reading and migration mechanisms, ensuring consistency with existing patterns.

Key Features

  • Intelligent Comparison: Automatically detects differences between model definitions and database schema
  • Idempotent: Safe to run multiple times - only applies necessary changes
  • Data Preservation: Existing data is preserved during schema updates
  • Transaction Safety: All changes are wrapped in a transaction
  • Method Chaining: Returns schema object to allow method chaining
  • Comprehensive: Handles missing tables, column changes, constraints, and relationships

Testing

Added comprehensive tests covering:

  • Basic update functionality with single and multiple tables
  • Missing table creation during updates
  • Idempotent behavior (multiple updates are safe)
  • Data preservation during schema changes
  • Method chaining capabilities
  • Complex schemas with foreign key relationships

All existing tests continue to pass, ensuring no breaking changes.

Usage Example

use Red;
use Red::Schema;

# Define your models
model User {
    has Int $.id   is serial;
    has Str $.name is column;
}

# Create schema
my $schema = schema(User);
$schema.create;

# Later, after modifying your model definitions...
# Just call update to apply changes automatically
$schema.update;

Fixes #482.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot avatar Sep 11 '25 02:09 Copilot