Skip to content

Migration Guide - Old to New Structure

This guide helps you migrate existing PGRestify projects from the old numbered file structure to the new table-based folder structure.

Overview

PGRestify has evolved from numbered SQL files to a table-based folder structure for better organization and maintainability.

What's Changing

From (Old Structure):

sql/schemas/
├── 01_main.sql      # All tables
├── 02_rls.sql       # All RLS policies
├── 03_views.sql     # All views  
├── 04_triggers.sql  # All triggers
└── 05_indexes.sql   # All indexes

To (New Structure):

sql/schemas/
├── _setup/
│   └── table.sql          # Roles, extensions, permissions
├── users/
│   ├── table.sql          # Users table definition
│   ├── rls.sql            # Users RLS policies
│   ├── triggers.sql       # Users triggers
│   ├── indexes.sql        # Users indexes
│   └── views.sql          # Users-related views
└── [other_tables]/
    └── [same structure]

Automatic Migration

Using the Restructure Command

The safest way to migrate is using the built-in restructure command:

bash
# 1. Preview the migration (recommended first step)
pgrestify api schema restructure --dry-run

Example Output:

🔍 Analyzing existing SQL structure...

Found old structure files:
✅ sql/schemas/01_main.sql (3 tables found)
✅ sql/schemas/02_rls.sql (8 policies found)  
✅ sql/schemas/03_views.sql (2 views found)
✅ sql/schemas/04_triggers.sql (3 triggers found)
✅ sql/schemas/05_indexes.sql (5 indexes found)

Proposed migration:
📁 sql/schemas/users/
  ├── table.sql    (CREATE TABLE users...)
  ├── rls.sql      (3 policies)
  ├── triggers.sql (1 trigger)
  └── indexes.sql  (2 indexes)

📁 sql/schemas/posts/  
  ├── table.sql    (CREATE TABLE posts...)
  ├── rls.sql      (4 policies)
  ├── views.sql    (1 view: user_posts)
  └── indexes.sql  (2 indexes)

📁 sql/schemas/comments/
  ├── table.sql    (CREATE TABLE comments...)
  ├── rls.sql      (1 policy)
  ├── triggers.sql (1 trigger)
  └── indexes.sql  (1 index)

📁 sql/schemas/_setup/
  └── table.sql    (Extensions, roles, permissions)

Use --backup flag to proceed with migration.
bash
# 2. Perform migration with backup (recommended)
pgrestify api schema restructure --backup

Migration Process:

  1. Creates backup of old structure in sql/backup_YYYYMMDD_HHMMSS/
  2. Analyzes each numbered file to identify table ownership
  3. Creates table folders with appropriate files
  4. Distributes SQL statements to correct locations
  5. Preserves comments and formatting
  6. Validates new structure
bash
# 3. Force migration (overwrite existing folders)
pgrestify api schema restructure --force

Use --force when:

  • You've already tried migration and want to overwrite
  • You have conflicting table folders to replace
  • You're confident about overwriting existing work

Manual Migration Steps

If you prefer manual migration or need to customize the process:

Step 1: Analyze Your Current Structure

First, understand what you have:

bash
# List your current SQL files
ls -la sql/schemas/

# Check file contents
head -20 sql/schemas/01_main.sql
head -20 sql/schemas/02_rls.sql

Step 2: Identify Tables

Look through 01_main.sql to identify all your tables:

sql
-- Example 01_main.sql content:
CREATE TABLE api.users (...);
CREATE TABLE api.posts (...);  
CREATE TABLE api.comments (...);

Step 3: Create Table Folders

bash
# Create folder structure
mkdir -p sql/schemas/_setup
mkdir -p sql/schemas/users
mkdir -p sql/schemas/posts
mkdir -p sql/schemas/comments

# Create standard files
touch sql/schemas/_setup/table.sql
touch sql/schemas/users/{table,rls,triggers,indexes,views}.sql
touch sql/schemas/posts/{table,rls,triggers,indexes,views}.sql
touch sql/schemas/comments/{table,rls,triggers,indexes,views}.sql

Step 4: Distribute SQL Content

Extract Extensions and Roles (to _setup/table.sql):

sql
-- Move these from 01_main.sql to sql/schemas/_setup/table.sql:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE ROLE web_anon NOLOGIN;
CREATE ROLE web_user NOLOGIN;
-- etc.

Extract Table Definitions:

sql
-- Move CREATE TABLE api.users from 01_main.sql 
-- to sql/schemas/users/table.sql

-- Move CREATE TABLE api.posts from 01_main.sql
-- to sql/schemas/posts/table.sql

Extract RLS Policies:

sql
-- Move policies from 02_rls.sql to appropriate table folders:
-- Users policies → sql/schemas/users/rls.sql
-- Posts policies → sql/schemas/posts/rls.sql

Extract Views:

sql
-- Move views from 03_views.sql to primary table folders:
-- user_posts view → sql/schemas/users/views.sql (if primarily about users)
-- post_stats view → sql/schemas/posts/views.sql (if primarily about posts)

Extract Triggers and Indexes:

sql
-- Move from 04_triggers.sql and 05_indexes.sql to table folders
-- Based on which table they operate on

Step 5: Validate Migration

bash
# Test the new structure
pgrestify api migrate --dry-run

# If successful, run actual migration
pgrestify api migrate --docker

Common Migration Scenarios

Scenario 1: Basic Blog Project

Before:

sql/schemas/
├── 01_main.sql     (users, posts, comments tables)
├── 02_rls.sql      (8 mixed policies)
└── 03_views.sql    (user_posts view)

After:

sql/schemas/
├── _setup/table.sql      (extensions, roles)
├── users/
│   ├── table.sql         (users table)
│   ├── rls.sql           (3 user policies)
│   └── views.sql         (user_posts view)
├── posts/
│   ├── table.sql         (posts table)
│   └── rls.sql           (4 post policies)
└── comments/
    ├── table.sql         (comments table)
    └── rls.sql           (1 comment policy)

Scenario 2: E-commerce Platform

Before:

sql/schemas/
├── 01_main.sql     (customers, products, orders, order_items)
├── 02_rls.sql      (15 mixed policies)
├── 04_triggers.sql (audit triggers)
└── 05_indexes.sql  (performance indexes)

After:

sql/schemas/
├── _setup/table.sql
├── customers/
│   ├── table.sql, rls.sql, triggers.sql, indexes.sql
├── products/  
│   ├── table.sql, rls.sql, indexes.sql, views.sql
├── orders/
│   ├── table.sql, rls.sql, triggers.sql, views.sql
└── order_items/
    ├── table.sql, rls.sql, indexes.sql

Post-Migration Tasks

1. Update Scripts

Update any custom scripts that reference old paths:

Before:

bash
# Old script
psql -f sql/schemas/01_main.sql
psql -f sql/schemas/02_rls.sql

After:

bash
# Use migration command instead
pgrestify api migrate --docker

2. Update Documentation

Update project README and documentation:

markdown
## Database Schema

Our database schema is organized in table-based folders:

- `sql/schemas/users/` - User management
- `sql/schemas/posts/` - Content management  
- `sql/schemas/comments/` - Comment system

To apply schema: `pgrestify api migrate`

3. Update CI/CD

Update deployment scripts:

Before:

yaml
# Old CI/CD
- run: psql $DATABASE_URL -f sql/schemas/01_main.sql
- run: psql $DATABASE_URL -f sql/schemas/02_rls.sql

After:

yaml
# New CI/CD
- run: pgrestify api migrate --docker

4. Team Communication

Inform your team about the new structure:

  1. Pull latest changes with new structure
  2. Run migration on their local environment
  3. Update their scripts and workflows
  4. Use new commands for adding features

Rollback Strategy

If you need to rollback the migration:

1. Restore from Backup

bash
# Restore from automatic backup
cp -r sql/backup_20250831_143045/* sql/schemas/

# Remove new structure
rm -rf sql/schemas/users/
rm -rf sql/schemas/posts/
# etc.

2. Manual Rollback

Create a single file from table folders:

bash
# Combine all table.sql files
cat sql/schemas/*/table.sql > sql/schemas/01_main.sql

# Combine all rls.sql files  
cat sql/schemas/*/rls.sql > sql/schemas/02_rls.sql

# etc.

Validation

Before Migration

Verify your current setup works:

bash
# Test current migrations
psql $DATABASE_URL -f sql/schemas/01_main.sql
psql $DATABASE_URL -f sql/schemas/02_rls.sql

After Migration

Verify the new structure works:

bash
# Test new migrations
pgrestify api migrate --dry-run
pgrestify api migrate --docker

Validation Checklist

  • [ ] All tables migrate successfully
  • [ ] All RLS policies are preserved
  • [ ] Foreign key relationships work
  • [ ] Views execute without errors
  • [ ] Triggers fire correctly
  • [ ] Indexes are created
  • [ ] Application connects and works
  • [ ] Authentication still works
  • [ ] All team members can migrate

Getting Help

If you encounter issues during migration:

bash
# Validate your project
pgrestify validate

# Check for common issues
pgrestify validate --check-rls --check-permissions

# Get detailed help
pgrestify api schema restructure --help

Common Issues:

  • Parse errors: Complex SQL might not parse correctly - review and manually adjust
  • Dependency conflicts: Foreign keys in wrong order - the system handles this automatically
  • Missing files: Some table folders might be empty - this is normal for tables without triggers/views
  • Permission issues: File system permissions - ensure write access to sql/ directory

Next Steps

After successful migration:

The table-based structure will make your PGRestify project more maintainable and team-friendly!

Released under the MIT License.