diff --git a/warehouse/migrations/versions/ab199e81677d_create_organization_models.py b/warehouse/migrations/versions/ab199e81677d_create_organization_models.py new file mode 100644 index 000000000000..c97abb8a5369 --- /dev/null +++ b/warehouse/migrations/versions/ab199e81677d_create_organization_models.py @@ -0,0 +1,274 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Create Organization models + +Revision ID: ab199e81677d +Revises: 84262e097c26 +Create Date: 2022-04-13 15:15:30.479559 +""" + +import sqlalchemy as sa + +from alembic import op +from sqlalchemy.dialects import postgresql + +revision = "ab199e81677d" +down_revision = "84262e097c26" + +# Note: It is VERY important to ensure that a migration does not lock for a +# long period of time and to ensure that each individual migration does +# not break compatibility with the *previous* version of the code base. +# This is because the migrations will be ran automatically as part of the +# deployment process, but while the previous version of the code is still +# up and running. Thus backwards incompatible changes must be broken up +# over multiple migrations inside of multiple pull requests in order to +# phase them in over multiple deploys. + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "organizations", + sa.Column( + "id", + postgresql.UUID(as_uuid=True), + server_default=sa.text("gen_random_uuid()"), + nullable=False, + ), + sa.Column("name", sa.Text(), nullable=False), + sa.Column("display_name", sa.Text(), nullable=False), + sa.Column( + "orgtype", + sa.Enum("Community", "Company", name="organizationtype"), + nullable=False, + ), + sa.Column("link_url", sqlalchemy_utils.types.url.URLType(), nullable=False), + sa.Column("description", sa.Text(), nullable=False), + sa.Column("is_active", sa.Boolean(), nullable=False), + sa.Column("is_approved", sa.Boolean(), nullable=True), + sa.Column( + "created", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("date_approved", sa.DateTime(), nullable=True), + sa.CheckConstraint( + "name ~* '^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$'::text", + name="organizations_valid_name", + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + op.f("ix_organizations_created"), "organizations", ["created"], unique=False + ) + op.create_table( + "organization_invitations", + sa.Column( + "id", + postgresql.UUID(as_uuid=True), + server_default=sa.text("gen_random_uuid()"), + nullable=False, + ), + sa.Column( + "invite_status", + sa.Enum("pending", "expired", name="organizationinvitationstatus"), + nullable=False, + ), + sa.Column("token", sa.Text(), nullable=False), + sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.Column("organization_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint( + ["organization_id"], + ["organizations.id"], + onupdate="CASCADE", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["user_id"], ["users.id"], onupdate="CASCADE", ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint( + "user_id", + "organization_id", + name="_organization_invitations_user_organization_uc", + ), + ) + op.create_index( + op.f("ix_organization_invitations_organization_id"), + "organization_invitations", + ["organization_id"], + unique=False, + ) + op.create_index( + op.f("ix_organization_invitations_user_id"), + "organization_invitations", + ["user_id"], + unique=False, + ) + op.create_index( + "organization_invitations_user_id_idx", + "organization_invitations", + ["user_id"], + unique=False, + ) + op.create_table( + "organization_name_catalog", + sa.Column( + "id", + postgresql.UUID(as_uuid=True), + server_default=sa.text("gen_random_uuid()"), + nullable=False, + ), + sa.Column("name", sa.Text(), nullable=False), + sa.Column("organization_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint( + ["organization_id"], + ["organizations.id"], + onupdate="CASCADE", + ondelete="CASCADE", + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint( + "name", + "organization_id", + name="_organization_name_catalog_name_organization_uc", + ), + ) + op.create_index( + "organization_name_catalog_name_idx", + "organization_name_catalog", + ["name"], + unique=False, + ) + op.create_index( + "organization_name_catalog_organization_id_idx", + "organization_name_catalog", + ["organization_id"], + unique=False, + ) + op.create_table( + "organization_project", + sa.Column( + "id", + postgresql.UUID(as_uuid=True), + server_default=sa.text("gen_random_uuid()"), + nullable=False, + ), + sa.Column("is_active", sa.Boolean(), nullable=True), + sa.Column("organization_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.Column("project_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint( + ["organization_id"], + ["organizations.id"], + onupdate="CASCADE", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["project_id"], ["projects.id"], onupdate="CASCADE", ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint( + "organization_id", + "project_id", + name="_organization_project_organization_project_uc", + ), + ) + op.create_index( + "organization_project_organization_id_idx", + "organization_project", + ["organization_id"], + unique=False, + ) + op.create_index( + "organization_project_project_id_idx", + "organization_project", + ["project_id"], + unique=False, + ) + op.create_table( + "organization_roles", + sa.Column( + "id", + postgresql.UUID(as_uuid=True), + server_default=sa.text("gen_random_uuid()"), + nullable=False, + ), + sa.Column("role_name", sa.Text(), nullable=False), + sa.Column("user_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.Column("organization_id", postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint( + ["organization_id"], + ["organizations.id"], + onupdate="CASCADE", + ondelete="CASCADE", + ), + sa.ForeignKeyConstraint( + ["user_id"], ["users.id"], onupdate="CASCADE", ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint( + "user_id", + "organization_id", + name="_organization_roles_user_organization_uc", + ), + ) + op.create_index( + "organization_roles_organization_id_idx", + "organization_roles", + ["organization_id"], + unique=False, + ) + op.create_index( + "organization_roles_user_id_idx", + "organization_roles", + ["user_id"], + unique=False, + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index("organization_roles_user_id_idx", table_name="organization_roles") + op.drop_index( + "organization_roles_organization_id_idx", table_name="organization_roles" + ) + op.drop_table("organization_roles") + op.drop_index( + "organization_project_project_id_idx", table_name="organization_project" + ) + op.drop_index( + "organization_project_organization_id_idx", table_name="organization_project" + ) + op.drop_table("organization_project") + op.drop_index( + "organization_name_catalog_organization_id_idx", + table_name="organization_name_catalog", + ) + op.drop_index( + "organization_name_catalog_name_idx", table_name="organization_name_catalog" + ) + op.drop_table("organization_name_catalog") + op.drop_index( + "organization_invitations_user_id_idx", table_name="organization_invitations" + ) + op.drop_index( + op.f("ix_organization_invitations_user_id"), + table_name="organization_invitations", + ) + op.drop_index( + op.f("ix_organization_invitations_organization_id"), + table_name="organization_invitations", + ) + op.drop_table("organization_invitations") + op.drop_index(op.f("ix_organizations_created"), table_name="organizations") + op.drop_table("organizations") + # ### end Alembic commands ###