gate2: fix duplicate column/index in migrations for fresh DB installation
This commit is contained in:
@@ -46,7 +46,7 @@ def upgrade() -> None:
|
|||||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
||||||
sa.UniqueConstraint("tenant_id", "email", name="uq_users_tenant_email"),
|
sa.UniqueConstraint("tenant_id", "email", name="uq_users_tenant_email"),
|
||||||
)
|
)
|
||||||
op.create_index("ix_users_tenant_id", "users", ["tenant_id"])
|
op.execute("CREATE INDEX IF NOT EXISTS ix_users_tenant_id ON users (tenant_id)")
|
||||||
op.create_index("ix_users_email", "users", ["email"])
|
op.create_index("ix_users_email", "users", ["email"])
|
||||||
|
|
||||||
# user_tenants
|
# user_tenants
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ def upgrade() -> None:
|
|||||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
||||||
)
|
)
|
||||||
op.create_index("ix_contacts_tenant_id", "contacts", ["tenant_id"])
|
op.create_index("ix_contacts_tenant_id", "contacts", ["tenant_id"])
|
||||||
op.create_index("ix_contacts_tenant_deleted", "contacts", ["tenant_id", "deleted_at"])
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_tenant_deleted ON contacts (tenant_id, deleted_at)")
|
||||||
op.create_index("ix_contacts_tenant_name", "contacts", ["tenant_id", "last_name", "first_name"])
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_tenant_name ON contacts (tenant_id, last_name, first_name)")
|
||||||
op.create_index("ix_contacts_email", "contacts", ["email"])
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_email ON contacts (email)")
|
||||||
|
|
||||||
# --- company_contacts (N:M join) ---
|
# --- company_contacts (N:M join) ---
|
||||||
op.create_table(
|
op.create_table(
|
||||||
|
|||||||
@@ -20,16 +20,8 @@ depends_on: Union[str, Sequence[str], None] = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
op.add_column(
|
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id UUID REFERENCES roles(id) ON DELETE SET NULL")
|
||||||
"users",
|
op.execute("CREATE INDEX IF NOT EXISTS ix_users_role_id ON users (role_id)")
|
||||||
sa.Column(
|
|
||||||
"role_id",
|
|
||||||
postgresql.UUID(as_uuid=True),
|
|
||||||
sa.ForeignKey("roles.id", ondelete="SET NULL"),
|
|
||||||
nullable=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
op.create_index("ix_users_role_id", "users", ["role_id"])
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -20,18 +20,18 @@ depends_on: Union[str, Sequence[str], None] = None
|
|||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
# Add address columns to companies
|
# Add address columns to companies
|
||||||
op.add_column("companies", sa.Column("address_street", sa.String(255), nullable=True))
|
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS address_street VARCHAR(255)")
|
||||||
op.add_column("companies", sa.Column("address_city", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS address_city VARCHAR(100)")
|
||||||
op.add_column("companies", sa.Column("address_zip", sa.String(20), nullable=True))
|
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS address_zip VARCHAR(20)")
|
||||||
op.add_column("companies", sa.Column("address_country", sa.String(2), nullable=True))
|
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS address_country VARCHAR(2)")
|
||||||
op.add_column("companies", sa.Column("address_state", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE companies ADD COLUMN IF NOT EXISTS address_state VARCHAR(100)")
|
||||||
|
|
||||||
# Add address columns to contacts
|
# Add address columns to contacts
|
||||||
op.add_column("contacts", sa.Column("address_street", sa.String(255), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS address_street VARCHAR(255)")
|
||||||
op.add_column("contacts", sa.Column("address_city", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS address_city VARCHAR(100)")
|
||||||
op.add_column("contacts", sa.Column("address_zip", sa.String(20), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS address_zip VARCHAR(20)")
|
||||||
op.add_column("contacts", sa.Column("address_country", sa.String(2), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS address_country VARCHAR(2)")
|
||||||
op.add_column("contacts", sa.Column("address_state", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS address_state VARCHAR(100)")
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -15,14 +15,8 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
# Add missing columns from TimestampMixin and SoftDeleteMixin
|
# Add missing columns from TimestampMixin and SoftDeleteMixin
|
||||||
op.add_column(
|
op.execute("ALTER TABLE notification_preferences ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
"notification_preferences",
|
op.execute("ALTER TABLE notification_preferences ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMPTZ")
|
||||||
sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
|
||||||
)
|
|
||||||
op.add_column(
|
|
||||||
"notification_preferences",
|
|
||||||
sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -161,11 +161,14 @@ def upgrade() -> None:
|
|||||||
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()),
|
||||||
sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
|
sa.Column("deleted_at", sa.DateTime(timezone=True), nullable=True),
|
||||||
)
|
)
|
||||||
op.create_index("ix_contacts_tenant_deleted", "contacts", ["tenant_id", "deleted_at"])
|
op.execute("DROP INDEX IF EXISTS ix_contacts_tenant_deleted")
|
||||||
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_tenant_deleted ON contacts (tenant_id, deleted_at)")
|
||||||
op.create_index("ix_contacts_tenant_type", "contacts", ["tenant_id", "type"])
|
op.create_index("ix_contacts_tenant_type", "contacts", ["tenant_id", "type"])
|
||||||
op.create_index("ix_contacts_tenant_name", "contacts", ["tenant_id", "name"])
|
op.execute("DROP INDEX IF EXISTS ix_contacts_tenant_name")
|
||||||
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_tenant_name ON contacts (tenant_id, name)")
|
||||||
op.create_index("ix_contacts_tenant_displayname", "contacts", ["tenant_id", "displayname"])
|
op.create_index("ix_contacts_tenant_displayname", "contacts", ["tenant_id", "displayname"])
|
||||||
op.create_index("ix_contacts_email", "contacts", ["email_1"])
|
op.execute("DROP INDEX IF EXISTS ix_contacts_email")
|
||||||
|
op.execute("CREATE INDEX IF NOT EXISTS ix_contacts_email ON contacts (email_1)")
|
||||||
op.create_index("ix_contacts_code", "contacts", ["code"])
|
op.create_index("ix_contacts_code", "contacts", ["code"])
|
||||||
op.create_index("ix_contacts_search_vec", "contacts", ["search_tsv"], postgresql_using="gin")
|
op.create_index("ix_contacts_search_vec", "contacts", ["search_tsv"], postgresql_using="gin")
|
||||||
|
|
||||||
@@ -202,8 +205,8 @@ def upgrade() -> None:
|
|||||||
op.create_index("ix_contactpersons_email", "contactpersons", ["email"])
|
op.create_index("ix_contactpersons_email", "contactpersons", ["email"])
|
||||||
|
|
||||||
# ── 4. Add FK columns to contacts that reference contactpersons ───
|
# ── 4. Add FK columns to contacts that reference contactpersons ───
|
||||||
op.add_column("contacts", sa.Column("default_person_id", UUID(as_uuid=True), sa.ForeignKey("contactpersons.id", ondelete="SET NULL"), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS default_person_id UUID REFERENCES contactpersons(id) ON DELETE SET NULL")
|
||||||
op.add_column("contacts", sa.Column("admin_contactperson_id", UUID(as_uuid=True), sa.ForeignKey("contactpersons.id", ondelete="SET NULL"), nullable=True))
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS admin_contactperson_id UUID REFERENCES contactpersons(id) ON DELETE SET NULL")
|
||||||
|
|
||||||
# ── 5. Migrate data from old tables ────────────────────────────────
|
# ── 5. Migrate data from old tables ────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ def upgrade():
|
|||||||
op.create_index("ix_contact_folders_user", "contact_folders", ["user_id"])
|
op.create_index("ix_contact_folders_user", "contact_folders", ["user_id"])
|
||||||
|
|
||||||
# 2. Add folder_id column to contacts
|
# 2. Add folder_id column to contacts
|
||||||
op.add_column(
|
op.execute("ALTER TABLE contacts ADD COLUMN IF NOT EXISTS folder_id UUID REFERENCES contact_folders(id) ON DELETE SET NULL")
|
||||||
"contacts",
|
|
||||||
sa.Column("folder_id", UUID(as_uuid=True), sa.ForeignKey("contact_folders.id", ondelete="SET NULL"), nullable=True),
|
|
||||||
)
|
|
||||||
op.create_index("ix_contacts_folder_id", "contacts", ["folder_id"])
|
op.create_index("ix_contacts_folder_id", "contacts", ["folder_id"])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ down_revision = "0022_contact_folders"
|
|||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
op.add_column("system_settings", sa.Column("theme_primary_color", sa.String(20), nullable=False, server_default="#2563eb"))
|
op.execute("ALTER TABLE system_settings ADD COLUMN IF NOT EXISTS theme_primary_color VARCHAR(20) NOT NULL DEFAULT '#2563eb'")
|
||||||
op.add_column("system_settings", sa.Column("theme_accent_color", sa.String(20), nullable=False, server_default="#d946ef"))
|
op.execute("ALTER TABLE system_settings ADD COLUMN IF NOT EXISTS theme_accent_color VARCHAR(20) NOT NULL DEFAULT '#d946ef'")
|
||||||
op.add_column("system_settings", sa.Column("theme_font_family", sa.String(100), nullable=False, server_default="Inter"))
|
op.execute("ALTER TABLE system_settings ADD COLUMN IF NOT EXISTS theme_font_family VARCHAR(100) NOT NULL DEFAULT 'Inter'")
|
||||||
op.add_column("system_settings", sa.Column("theme_border_radius", sa.String(20), nullable=False, server_default="0.5rem"))
|
op.execute("ALTER TABLE system_settings ADD COLUMN IF NOT EXISTS theme_border_radius VARCHAR(20) NOT NULL DEFAULT '0.5rem'")
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ down_revision = "0023_theme_customization"
|
|||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
op.add_column("ai_proactive_settings", sa.Column("heartbeat_enabled", sa.Boolean(), nullable=False, server_default=sa.text("true")))
|
op.execute("ALTER TABLE ai_proactive_settings ADD COLUMN IF NOT EXISTS heartbeat_enabled BOOLEAN NOT NULL DEFAULT true")
|
||||||
op.add_column("ai_proactive_settings", sa.Column("heartbeat_interval_seconds", sa.Integer(), nullable=False, server_default=sa.text("300")))
|
op.execute("ALTER TABLE ai_proactive_settings ADD COLUMN IF NOT EXISTS heartbeat_interval_seconds INTEGER NOT NULL DEFAULT 300")
|
||||||
op.add_column("ai_proactive_settings", sa.Column("heartbeat_target_room", sa.String(200), nullable=False, server_default="Live KI"))
|
op.execute("ALTER TABLE ai_proactive_settings ADD COLUMN IF NOT EXISTS heartbeat_target_room VARCHAR(200) NOT NULL DEFAULT 'Live KI'")
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ down_revision = "0025_entity_history"
|
|||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
op.add_column("mail_accounts", sa.Column("password_salt", sa.String(64), nullable=False, server_default=""))
|
op.execute("ALTER TABLE mail_accounts ADD COLUMN IF NOT EXISTS password_salt VARCHAR(64) NOT NULL DEFAULT ''")
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ depends_on = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
op.add_column("users", sa.Column("first_name", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS first_name VARCHAR(100)")
|
||||||
op.add_column("users", sa.Column("last_name", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS last_name VARCHAR(100)")
|
||||||
op.add_column("users", sa.Column("avatar_url", sa.String(500), nullable=True))
|
op.execute("ALTER TABLE users ADD COLUMN IF NOT EXISTS avatar_url VARCHAR(500)")
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ depends_on: Union[str, Sequence[str], None] = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
op.add_column("system_settings", sa.Column("automation_config", JSONB, nullable=True))
|
op.execute("ALTER TABLE system_settings ADD COLUMN IF NOT EXISTS automation_config JSONB")
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -20,20 +20,8 @@ depends_on = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
op.add_column(
|
op.execute("ALTER TABLE mail_accounts ADD COLUMN IF NOT EXISTS owner_id UUID REFERENCES users(id) ON DELETE SET NULL")
|
||||||
"mail_accounts",
|
op.execute("CREATE INDEX IF NOT EXISTS ix_mail_accounts_owner ON mail_accounts (owner_id)")
|
||||||
sa.Column(
|
|
||||||
"owner_id",
|
|
||||||
UUID(as_uuid=True),
|
|
||||||
sa.ForeignKey("users.id", ondelete="SET NULL"),
|
|
||||||
nullable=True,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
op.create_index(
|
|
||||||
"ix_mail_accounts_owner",
|
|
||||||
"mail_accounts",
|
|
||||||
["owner_id"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ depends_on = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
op.add_column("notifications", sa.Column("entity_type", sa.String(50), nullable=True, index=True))
|
op.execute("ALTER TABLE notifications ADD COLUMN IF NOT EXISTS entity_type VARCHAR(50)")
|
||||||
op.add_column("notifications", sa.Column("entity_id", UUID(as_uuid=True), nullable=True))
|
op.execute("CREATE INDEX IF NOT EXISTS ix_notifications_entity_type ON notifications (entity_type)")
|
||||||
|
op.execute("ALTER TABLE notifications ADD COLUMN IF NOT EXISTS entity_id UUID")
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
# workspace_users: add created_at and updated_at
|
# workspace_users: add created_at and updated_at
|
||||||
op.add_column("workspace_users", sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("NOW()"), nullable=False))
|
op.execute("ALTER TABLE workspace_users ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
op.add_column("workspace_users", sa.Column("updated_at", sa.DateTime(timezone=True), server_default=sa.text("NOW()"), nullable=False))
|
op.execute("ALTER TABLE workspace_users ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
|
|
||||||
# workspace_widgets: already has created_at/updated_at from migration 0072
|
# workspace_widgets: already has created_at/updated_at from migration 0072
|
||||||
# workspace_modules: already has created_at/updated_at from migration 0072
|
# workspace_modules: already has created_at/updated_at from migration 0072
|
||||||
|
|||||||
@@ -30,11 +30,11 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
# 1. Add envelope columns to event_outbox
|
# 1. Add envelope columns to event_outbox
|
||||||
op.add_column("event_outbox", sa.Column("aggregate_type", sa.String(100), nullable=True))
|
op.execute("ALTER TABLE event_outbox ADD COLUMN IF NOT EXISTS aggregate_type VARCHAR(100)")
|
||||||
op.add_column("event_outbox", sa.Column("aggregate_id", PGUUID(as_uuid=True), nullable=True))
|
op.execute("ALTER TABLE event_outbox ADD COLUMN IF NOT EXISTS aggregate_id UUID")
|
||||||
op.add_column("event_outbox", sa.Column("occurred_at", sa.DateTime(timezone=True), server_default=sa.text("NOW()"), nullable=False))
|
op.execute("ALTER TABLE event_outbox ADD COLUMN IF NOT EXISTS occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
op.add_column("event_outbox", sa.Column("correlation_id", PGUUID(as_uuid=True), nullable=True))
|
op.execute("ALTER TABLE event_outbox ADD COLUMN IF NOT EXISTS correlation_id UUID")
|
||||||
op.add_column("event_outbox", sa.Column("schema_version", sa.Integer, nullable=False, server_default=sa.text("1")))
|
op.execute("ALTER TABLE event_outbox ADD COLUMN IF NOT EXISTS schema_version INTEGER NOT NULL DEFAULT 1")
|
||||||
|
|
||||||
op.execute("CREATE INDEX IF NOT EXISTS ix_event_outbox_aggregate ON event_outbox (tenant_id, aggregate_type, aggregate_id)")
|
op.execute("CREATE INDEX IF NOT EXISTS ix_event_outbox_aggregate ON event_outbox (tenant_id, aggregate_type, aggregate_id)")
|
||||||
op.execute("CREATE INDEX IF NOT EXISTS ix_event_outbox_correlation ON event_outbox (correlation_id)")
|
op.execute("CREATE INDEX IF NOT EXISTS ix_event_outbox_correlation ON event_outbox (correlation_id)")
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ depends_on = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
op.add_column("password_reset_tokens", sa.Column("created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
|
op.execute("ALTER TABLE password_reset_tokens ADD COLUMN IF NOT EXISTS created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
op.add_column("password_reset_tokens", sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.func.now()))
|
op.execute("ALTER TABLE password_reset_tokens ADD COLUMN IF NOT EXISTS updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()")
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user