chore: Consolidate migrations into a single file

This commit is contained in:
Eric Hare
2026-05-14 11:51:23 -07:00
parent 2acf685b84
commit 1237e42906
2 changed files with 113 additions and 202 deletions

View File

@ -1,4 +1,4 @@
"""add RBAC plugin tables role, user_role, resource_permission, audit_log
"""add RBAC plugin tables rbac_role, rbac_user_role, rbac_resource_permission, rbac_audit_log
Revision ID: c5d6e7f8g9h0
Revises: mb01b2c3d4e5
@ -23,46 +23,77 @@ depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
conn = op.get_bind()
if not migration.table_exists("role", conn):
if not migration.table_exists("rbac_role", conn):
op.create_table(
"role",
"rbac_role",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("name", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
sa.Column("is_system", sa.Boolean(), nullable=False),
sa.Column("permissions", sa.JSON(), nullable=False), # Stores list[str]
sa.Column("parent_role_id", sa.Uuid(), nullable=True),
sa.Column("workspace_id", sa.Uuid(), nullable=True),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.Column("updated_at", sa.DateTime(), nullable=False),
sa.Column("created_by", sa.Uuid(), nullable=True),
sa.ForeignKeyConstraint(
["parent_role_id"],
["rbac_role.id"],
name="fk_rbac_role_parent_role_id_rbac_role",
ondelete="SET NULL",
),
sa.ForeignKeyConstraint(
["created_by"],
["user.id"],
name="fk_rbac_role_created_by_user",
ondelete="SET NULL",
),
sa.PrimaryKeyConstraint("id"),
)
with op.batch_alter_table("role", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_role_name"), ["name"], unique=True)
with op.batch_alter_table("rbac_role", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_rbac_role_name"), ["name"], unique=True)
batch_op.create_index("ix_rbac_role_workspace_id", ["workspace_id"], unique=False)
if not migration.table_exists("user_role", conn):
if not migration.table_exists("rbac_user_role", conn):
op.create_table(
"user_role",
"rbac_user_role",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("user_id", sa.Uuid(), nullable=False),
sa.Column("role_id", sa.Uuid(), nullable=False),
sa.Column("assigned_at", sa.DateTime(), nullable=False),
sa.Column("assigned_by", sa.Uuid(), nullable=True),
sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["role_id"], ["role.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["assigned_by"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
name="fk_rbac_user_role_user_id_user",
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["role_id"],
["rbac_role.id"],
name="fk_rbac_user_role_role_id_rbac_role",
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["assigned_by"],
["user.id"],
name="fk_rbac_user_role_assigned_by_user",
ondelete="SET NULL",
),
sa.PrimaryKeyConstraint("id"),
)
with op.batch_alter_table("user_role", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_user_role_user_id"), ["user_id"], unique=False)
batch_op.create_index(batch_op.f("ix_user_role_role_id"), ["role_id"], unique=False)
with op.batch_alter_table("rbac_user_role", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_rbac_user_role_user_id"), ["user_id"], unique=False)
batch_op.create_index(batch_op.f("ix_rbac_user_role_role_id"), ["role_id"], unique=False)
batch_op.create_index(
batch_op.f("uq_user_role_user_role"),
"uq_rbac_user_role_user_role",
["user_id", "role_id"],
unique=True,
)
if not migration.table_exists("resource_permission", conn):
if not migration.table_exists("rbac_resource_permission", conn):
op.create_table(
"resource_permission",
"rbac_resource_permission",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("user_id", sa.Uuid(), nullable=False),
sa.Column("resource_type", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
@ -70,23 +101,41 @@ def upgrade() -> None:
sa.Column("permission", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column("granted_at", sa.DateTime(), nullable=False),
sa.Column("granted_by", sa.Uuid(), nullable=True),
sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="CASCADE"),
sa.ForeignKeyConstraint(["granted_by"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
name="fk_rbac_resource_permission_user_id_user",
ondelete="CASCADE",
),
sa.ForeignKeyConstraint(
["granted_by"],
["user.id"],
name="fk_rbac_resource_permission_granted_by_user",
ondelete="SET NULL",
),
sa.PrimaryKeyConstraint("id"),
)
with op.batch_alter_table("resource_permission", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_resource_permission_user_id"), ["user_id"], unique=False)
batch_op.create_index(batch_op.f("ix_resource_permission_resource_type"), ["resource_type"], unique=False)
batch_op.create_index(batch_op.f("ix_resource_permission_resource_id"), ["resource_id"], unique=False)
with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_rbac_resource_permission_user_id"), ["user_id"], unique=False)
batch_op.create_index(
batch_op.f("ix_resource_permission_user_resource"),
["user_id", "resource_type", "resource_id"],
batch_op.f("ix_rbac_resource_permission_resource_type"),
["resource_type"],
unique=False,
)
batch_op.create_index(
batch_op.f("ix_rbac_resource_permission_resource_id"),
["resource_id"],
unique=False,
)
batch_op.create_index(
"uq_rbac_resource_permission_user_resource_perm",
["user_id", "resource_type", "resource_id", "permission"],
unique=True,
)
if not migration.table_exists("audit_log", conn):
if not migration.table_exists("rbac_audit_log", conn):
op.create_table(
"audit_log",
"rbac_audit_log",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("user_id", sa.Uuid(), nullable=True),
sa.Column("action", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
@ -95,20 +144,25 @@ def upgrade() -> None:
sa.Column("result", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
sa.Column("details", sa.JSON(), nullable=True),
sa.Column("timestamp", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="SET NULL"),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
name="fk_rbac_audit_log_user_id_user",
ondelete="SET NULL",
),
sa.PrimaryKeyConstraint("id"),
)
with op.batch_alter_table("audit_log", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_audit_log_user_id"), ["user_id"], unique=False)
batch_op.create_index(batch_op.f("ix_audit_log_action"), ["action"], unique=False)
batch_op.create_index(batch_op.f("ix_audit_log_timestamp"), ["timestamp"], unique=False)
with op.batch_alter_table("rbac_audit_log", schema=None) as batch_op:
batch_op.create_index(batch_op.f("ix_rbac_audit_log_user_id"), ["user_id"], unique=False)
batch_op.create_index(batch_op.f("ix_rbac_audit_log_action"), ["action"], unique=False)
batch_op.create_index(batch_op.f("ix_rbac_audit_log_timestamp"), ["timestamp"], unique=False)
batch_op.create_index(
batch_op.f("ix_audit_log_user_timestamp"),
"ix_rbac_audit_log_user_timestamp",
["user_id", "timestamp"],
unique=False,
)
batch_op.create_index(
batch_op.f("ix_audit_log_resource"),
"ix_rbac_audit_log_resource",
["resource_type", "resource_id"],
unique=False,
)
@ -117,31 +171,32 @@ def upgrade() -> None:
def downgrade() -> None:
conn = op.get_bind()
if migration.table_exists("audit_log", conn):
with op.batch_alter_table("audit_log", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("ix_audit_log_resource"))
batch_op.drop_index(batch_op.f("ix_audit_log_user_timestamp"))
batch_op.drop_index(batch_op.f("ix_audit_log_timestamp"))
batch_op.drop_index(batch_op.f("ix_audit_log_action"))
batch_op.drop_index(batch_op.f("ix_audit_log_user_id"))
op.drop_table("audit_log")
if migration.table_exists("rbac_audit_log", conn):
with op.batch_alter_table("rbac_audit_log", schema=None) as batch_op:
batch_op.drop_index("ix_rbac_audit_log_resource")
batch_op.drop_index("ix_rbac_audit_log_user_timestamp")
batch_op.drop_index(batch_op.f("ix_rbac_audit_log_timestamp"))
batch_op.drop_index(batch_op.f("ix_rbac_audit_log_action"))
batch_op.drop_index(batch_op.f("ix_rbac_audit_log_user_id"))
op.drop_table("rbac_audit_log")
if migration.table_exists("resource_permission", conn):
with op.batch_alter_table("resource_permission", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("ix_resource_permission_user_resource"))
batch_op.drop_index(batch_op.f("ix_resource_permission_resource_id"))
batch_op.drop_index(batch_op.f("ix_resource_permission_resource_type"))
batch_op.drop_index(batch_op.f("ix_resource_permission_user_id"))
op.drop_table("resource_permission")
if migration.table_exists("rbac_resource_permission", conn):
with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op:
batch_op.drop_index("uq_rbac_resource_permission_user_resource_perm")
batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_resource_id"))
batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_resource_type"))
batch_op.drop_index(batch_op.f("ix_rbac_resource_permission_user_id"))
op.drop_table("rbac_resource_permission")
if migration.table_exists("user_role", conn):
with op.batch_alter_table("user_role", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("uq_user_role_user_role"))
batch_op.drop_index(batch_op.f("ix_user_role_role_id"))
batch_op.drop_index(batch_op.f("ix_user_role_user_id"))
op.drop_table("user_role")
if migration.table_exists("rbac_user_role", conn):
with op.batch_alter_table("rbac_user_role", schema=None) as batch_op:
batch_op.drop_index("uq_rbac_user_role_user_role")
batch_op.drop_index(batch_op.f("ix_rbac_user_role_role_id"))
batch_op.drop_index(batch_op.f("ix_rbac_user_role_user_id"))
op.drop_table("rbac_user_role")
if migration.table_exists("role", conn):
with op.batch_alter_table("role", schema=None) as batch_op:
batch_op.drop_index(batch_op.f("ix_role_name"))
op.drop_table("role")
if migration.table_exists("rbac_role", conn):
with op.batch_alter_table("rbac_role", schema=None) as batch_op:
batch_op.drop_index("ix_rbac_role_workspace_id")
batch_op.drop_index(batch_op.f("ix_rbac_role_name"))
op.drop_table("rbac_role")

View File

@ -1,144 +0,0 @@
"""rename rbac tables and add new columns
Revision ID: e2c8539167b1
Revises: c5d6e7f8g9h0
Create Date: 2026-05-14 11:37:32.663086
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
import sqlmodel
from langflow.utils import migration
# revision identifiers, used by Alembic.
revision: str = 'e2c8539167b1'
down_revision: Union[str, None] = 'c5d6e7f8g9h0'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
conn = op.get_bind()
# Rename tables (preserves data)
if migration.table_exists("role", conn):
op.rename_table("role", "rbac_role")
if migration.table_exists("user_role", conn):
op.rename_table("user_role", "rbac_user_role")
if migration.table_exists("resource_permission", conn):
op.rename_table("resource_permission", "rbac_resource_permission")
if migration.table_exists("audit_log", conn):
op.rename_table("audit_log", "rbac_audit_log")
# Add new columns to rbac_role
if migration.table_exists("rbac_role", conn):
with op.batch_alter_table("rbac_role", schema=None) as batch_op:
# Add parent_role_id for role inheritance
batch_op.add_column(sa.Column("parent_role_id", sa.Uuid(), nullable=True))
batch_op.create_foreign_key(
"fk_rbac_role_parent_role_id_rbac_role",
"rbac_role",
["parent_role_id"],
["id"],
ondelete="SET NULL"
)
# Add workspace_id for future workspace isolation
batch_op.add_column(sa.Column("workspace_id", sa.Uuid(), nullable=True))
batch_op.create_index("ix_rbac_role_workspace_id", ["workspace_id"], unique=False)
# Add created_by for audit trail
batch_op.add_column(sa.Column("created_by", sa.Uuid(), nullable=True))
batch_op.create_foreign_key(
"fk_rbac_role_created_by_user",
"user",
["created_by"],
["id"],
ondelete="SET NULL"
)
# Update rbac_resource_permission: change index to unique constraint
if migration.table_exists("rbac_resource_permission", conn):
with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op:
# Drop old non-unique index
batch_op.drop_index("ix_resource_permission_user_resource")
# Create new unique index
batch_op.create_index(
"uq_rbac_resource_permission_user_resource_perm",
["user_id", "resource_type", "resource_id", "permission"],
unique=True
)
# Update foreign key references in rbac_user_role
if migration.table_exists("rbac_user_role", conn):
with op.batch_alter_table("rbac_user_role", schema=None) as batch_op:
# Drop old foreign key to role table
batch_op.drop_constraint("fk_user_role_role_id_role", type_="foreignkey")
# Create new foreign key to rbac_role table
batch_op.create_foreign_key(
"fk_rbac_user_role_role_id_rbac_role",
"rbac_role",
["role_id"],
["id"],
ondelete="CASCADE"
)
def downgrade() -> None:
conn = op.get_bind()
# Remove new columns from rbac_role
if migration.table_exists("rbac_role", conn):
with op.batch_alter_table("rbac_role", schema=None) as batch_op:
batch_op.drop_constraint("fk_rbac_role_created_by_user", type_="foreignkey")
batch_op.drop_column("created_by")
batch_op.drop_index("ix_rbac_role_workspace_id")
batch_op.drop_column("workspace_id")
batch_op.drop_constraint("fk_rbac_role_parent_role_id_rbac_role", type_="foreignkey")
batch_op.drop_column("parent_role_id")
# Revert rbac_resource_permission index changes
if migration.table_exists("rbac_resource_permission", conn):
with op.batch_alter_table("rbac_resource_permission", schema=None) as batch_op:
batch_op.drop_index("uq_rbac_resource_permission_user_resource_perm")
batch_op.create_index(
"ix_resource_permission_user_resource",
["user_id", "resource_type", "resource_id"],
unique=False
)
# Revert foreign key in rbac_user_role
if migration.table_exists("rbac_user_role", conn):
with op.batch_alter_table("rbac_user_role", schema=None) as batch_op:
batch_op.drop_constraint("fk_rbac_user_role_role_id_rbac_role", type_="foreignkey")
batch_op.create_foreign_key(
"fk_user_role_role_id_role",
"role",
["role_id"],
["id"],
ondelete="CASCADE"
)
# Rename tables back
if migration.table_exists("rbac_audit_log", conn):
op.rename_table("rbac_audit_log", "audit_log")
if migration.table_exists("rbac_resource_permission", conn):
op.rename_table("rbac_resource_permission", "resource_permission")
if migration.table_exists("rbac_user_role", conn):
op.rename_table("rbac_user_role", "user_role")
if migration.table_exists("rbac_role", conn):
op.rename_table("rbac_role", "role")
# Made with Bob