backend changes
This commit is contained in:
parent
dd77bef0a9
commit
0339ca49a4
121
REQUIREMENT_PROCESSOR_MIGRATION_FIX.md
Normal file
121
REQUIREMENT_PROCESSOR_MIGRATION_FIX.md
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Deployment Fix Guide - Requirement Processor Migration Issue
|
||||||
|
|
||||||
|
## Problem Summary
|
||||||
|
The deployment failed due to a database migration constraint issue in the requirement processor service. The error was:
|
||||||
|
```
|
||||||
|
❌ Migration failed: 001_business_context_tables.sql - null value in column "service" of relation "schema_migrations" violates not-null constraint
|
||||||
|
```
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
The requirement processor's migration system was using an outdated schema for the `schema_migrations` table that didn't include the required `service` field, while the main database migration system expected this field to be present and non-null.
|
||||||
|
|
||||||
|
## Fix Applied
|
||||||
|
|
||||||
|
### 1. Updated Migration Script (`migrate.py`)
|
||||||
|
- ✅ Updated `schema_migrations` table schema to include `service` field
|
||||||
|
- ✅ Modified `is_applied()` function to check by both version and service
|
||||||
|
- ✅ Updated `mark_applied()` function to include service and description
|
||||||
|
- ✅ Fixed `run_migration()` function to use service parameter
|
||||||
|
|
||||||
|
### 2. Fixed Migration Files
|
||||||
|
- ✅ Removed foreign key constraint from initial migration to avoid dependency issues
|
||||||
|
- ✅ The second migration already handles the constraint properly
|
||||||
|
|
||||||
|
### 3. Created Fix Script
|
||||||
|
- ✅ Created `scripts/fix-requirement-processor-migration.sh` to clean up and restart the service
|
||||||
|
|
||||||
|
## Deployment Steps
|
||||||
|
|
||||||
|
### Option 1: Use the Fix Script (Recommended)
|
||||||
|
```bash
|
||||||
|
cd /home/ubuntu/codenuk-backend-live
|
||||||
|
./scripts/fix-requirement-processor-migration.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Manual Fix
|
||||||
|
```bash
|
||||||
|
# 1. Stop the requirement processor
|
||||||
|
docker compose stop requirement-processor
|
||||||
|
|
||||||
|
# 2. Clean up failed migration records
|
||||||
|
PGPASSWORD="password" psql -h localhost -p 5432 -U postgres -d dev_pipeline << 'EOF'
|
||||||
|
DELETE FROM schema_migrations WHERE service = 'requirement-processor' OR version LIKE '%.sql';
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 3. Restart the service
|
||||||
|
docker compose up -d requirement-processor
|
||||||
|
|
||||||
|
# 4. Check status
|
||||||
|
docker compose ps requirement-processor
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Full Redeploy
|
||||||
|
```bash
|
||||||
|
# Stop all services
|
||||||
|
docker compose down
|
||||||
|
|
||||||
|
# Clean up database (if needed)
|
||||||
|
PGPASSWORD="password" psql -h localhost -p 5432 -U postgres -d dev_pipeline << 'EOF'
|
||||||
|
DELETE FROM schema_migrations WHERE service = 'requirement-processor';
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Start all services
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. **Check Service Status**
|
||||||
|
```bash
|
||||||
|
docker compose ps requirement-processor
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check Migration Records**
|
||||||
|
```bash
|
||||||
|
PGPASSWORD="password" psql -h localhost -p 5432 -U postgres -d dev_pipeline << 'EOF'
|
||||||
|
SELECT service, version, applied_at, description
|
||||||
|
FROM schema_migrations
|
||||||
|
WHERE service = 'requirement-processor'
|
||||||
|
ORDER BY applied_at;
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Check Service Logs**
|
||||||
|
```bash
|
||||||
|
docker compose logs requirement-processor
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Test Health Endpoint**
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8001/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expected Results
|
||||||
|
|
||||||
|
After the fix:
|
||||||
|
- ✅ Requirement processor service should start successfully
|
||||||
|
- ✅ Migration records should show proper service field
|
||||||
|
- ✅ Health endpoint should return 200 OK
|
||||||
|
- ✅ All other services should continue running normally
|
||||||
|
|
||||||
|
## Prevention
|
||||||
|
|
||||||
|
To prevent this issue in the future:
|
||||||
|
1. Always ensure migration scripts use the correct `schema_migrations` table schema
|
||||||
|
2. Include service field in all migration tracking
|
||||||
|
3. Test migrations in development before deploying to production
|
||||||
|
4. Use the shared migration system consistently across all services
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If the issue persists:
|
||||||
|
1. Check database connectivity
|
||||||
|
2. Verify PostgreSQL is running
|
||||||
|
3. Check disk space and memory
|
||||||
|
4. Review all service logs
|
||||||
|
5. Consider a full database reset if necessary
|
||||||
|
|
||||||
|
## Files Modified
|
||||||
|
- `services/requirement-processor/migrations/migrate.py` - Updated migration system
|
||||||
|
- `services/requirement-processor/migrations/001_business_context_tables.sql` - Removed FK constraint
|
||||||
|
- `scripts/fix-requirement-processor-migration.sh` - Created fix script
|
||||||
80
scripts/fix-requirement-processor-migration.sh
Executable file
80
scripts/fix-requirement-processor-migration.sh
Executable file
@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Fix Requirement Processor Migration Issue
|
||||||
|
# This script fixes the schema_migrations constraint issue
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Database connection settings
|
||||||
|
DB_HOST=${DB_HOST:-"localhost"}
|
||||||
|
DB_PORT=${DB_PORT:-"5432"}
|
||||||
|
DB_USER=${DB_USER:-"postgres"}
|
||||||
|
DB_NAME=${DB_NAME:-"dev_pipeline"}
|
||||||
|
DB_PASSWORD=${DB_PASSWORD:-"password"}
|
||||||
|
|
||||||
|
log "🔧 Fixing Requirement Processor Migration Issue"
|
||||||
|
log "=============================================="
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if [ ! -f "docker-compose.yml" ]; then
|
||||||
|
error "Please run this script from the codenuk-backend-live directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "📋 Step 1: Stopping the requirement-processor service"
|
||||||
|
docker compose stop requirement-processor || true
|
||||||
|
|
||||||
|
log "📋 Step 2: Cleaning up failed migration records"
|
||||||
|
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" << 'EOF'
|
||||||
|
-- Remove any failed migration records for requirement-processor
|
||||||
|
DELETE FROM schema_migrations WHERE service = 'requirement-processor' OR version LIKE '%.sql';
|
||||||
|
|
||||||
|
-- Ensure the schema_migrations table has the correct structure
|
||||||
|
ALTER TABLE schema_migrations ALTER COLUMN service SET NOT NULL;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log "📋 Step 3: Restarting the requirement-processor service"
|
||||||
|
docker compose up -d requirement-processor
|
||||||
|
|
||||||
|
log "📋 Step 4: Waiting for service to be healthy"
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Check if the service is running
|
||||||
|
if docker compose ps requirement-processor | grep -q "Up"; then
|
||||||
|
log "✅ Requirement processor service is running"
|
||||||
|
else
|
||||||
|
error "❌ Requirement processor service failed to start"
|
||||||
|
docker compose logs requirement-processor
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "📋 Step 5: Verifying migration status"
|
||||||
|
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" << 'EOF'
|
||||||
|
-- Check migration status
|
||||||
|
SELECT service, version, applied_at, description
|
||||||
|
FROM schema_migrations
|
||||||
|
WHERE service = 'requirement-processor'
|
||||||
|
ORDER BY applied_at;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
log "✅ Migration fix completed!"
|
||||||
|
log "You can now restart the full deployment:"
|
||||||
|
log "docker compose up -d"
|
||||||
@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS business_context_responses (
|
|||||||
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
user_id UUID NOT NULL,
|
user_id UUID NOT NULL,
|
||||||
template_id UUID,
|
template_id UUID,
|
||||||
project_id UUID REFERENCES projects(id) ON DELETE CASCADE,
|
project_id UUID,
|
||||||
|
|
||||||
-- Simple JSONB structure with questions array
|
-- Simple JSONB structure with questions array
|
||||||
questions JSONB NOT NULL DEFAULT '[]'::jsonb,
|
questions JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||||
|
|||||||
@ -16,8 +16,11 @@ DATABASE_URL = os.getenv('DATABASE_URL', 'postgresql://postgres:password@localho
|
|||||||
|
|
||||||
SCHEMA_MIGRATIONS_TABLE_SQL = """
|
SCHEMA_MIGRATIONS_TABLE_SQL = """
|
||||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||||
version TEXT PRIMARY KEY,
|
id SERIAL PRIMARY KEY,
|
||||||
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
version VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
service VARCHAR(100) NOT NULL,
|
||||||
|
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
description TEXT
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -25,20 +28,24 @@ async def ensure_migrations_table(pool) -> None:
|
|||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
await conn.execute(SCHEMA_MIGRATIONS_TABLE_SQL)
|
await conn.execute(SCHEMA_MIGRATIONS_TABLE_SQL)
|
||||||
|
|
||||||
async def is_applied(pool, version: str) -> bool:
|
async def is_applied(pool, version: str, service: str = "requirement-processor") -> bool:
|
||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
row = await conn.fetchrow("SELECT 1 FROM schema_migrations WHERE version = $1", version)
|
row = await conn.fetchrow("SELECT 1 FROM schema_migrations WHERE version = $1 AND service = $2", version, service)
|
||||||
return row is not None
|
return row is not None
|
||||||
|
|
||||||
async def mark_applied(pool, version: str) -> None:
|
async def mark_applied(pool, version: str, service: str = "requirement-processor", description: str = None) -> None:
|
||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
await conn.execute("INSERT INTO schema_migrations(version) VALUES($1) ON CONFLICT (version) DO NOTHING", version)
|
await conn.execute(
|
||||||
|
"INSERT INTO schema_migrations(version, service, description) VALUES($1, $2, $3) ON CONFLICT (version) DO NOTHING",
|
||||||
|
version, service, description
|
||||||
|
)
|
||||||
|
|
||||||
async def run_migration(pool, migration_file):
|
async def run_migration(pool, migration_file):
|
||||||
"""Run a single migration file if not applied"""
|
"""Run a single migration file if not applied"""
|
||||||
version = migration_file.name
|
version = migration_file.name
|
||||||
|
service = "requirement-processor"
|
||||||
try:
|
try:
|
||||||
if await is_applied(pool, version):
|
if await is_applied(pool, version, service):
|
||||||
logger.info(f"⏭️ Skipping already applied migration: {version}")
|
logger.info(f"⏭️ Skipping already applied migration: {version}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -48,7 +55,7 @@ async def run_migration(pool, migration_file):
|
|||||||
async with pool.acquire() as conn:
|
async with pool.acquire() as conn:
|
||||||
await conn.execute(sql_content)
|
await conn.execute(sql_content)
|
||||||
|
|
||||||
await mark_applied(pool, version)
|
await mark_applied(pool, version, service, f"Requirement processor migration: {version}")
|
||||||
logger.info(f"✅ Migration completed: {version}")
|
logger.info(f"✅ Migration completed: {version}")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user