From 5f54468082829f82fb5606f809e367998efb3a34 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Thu, 20 Sep 2018 10:18:52 -0400 Subject: [PATCH] Timestamps and uuids everywhere --- ...9bf_initial.py => 359caaf8c5f1_initial.py} | 62 ++++++++++++------- atst/models/attachment.py | 6 +- atst/models/environment_role.py | 7 +-- atst/models/pe_number.py | 2 +- atst/models/request.py | 9 ++- atst/models/request_internal_comment.py | 4 +- atst/models/request_review.py | 8 +-- atst/models/request_status_event.py | 4 +- atst/models/role.py | 7 +-- atst/models/task_order.py | 8 +-- atst/models/user.py | 7 +-- atst/models/workspace_role.py | 6 +- tests/models/test_task_order.py | 5 +- 13 files changed, 74 insertions(+), 61 deletions(-) rename alembic/versions/{74ac90c019bf_initial.py => 359caaf8c5f1_initial.py} (80%) diff --git a/alembic/versions/74ac90c019bf_initial.py b/alembic/versions/359caaf8c5f1_initial.py similarity index 80% rename from alembic/versions/74ac90c019bf_initial.py rename to alembic/versions/359caaf8c5f1_initial.py index e0b43d55..8723a937 100644 --- a/alembic/versions/74ac90c019bf_initial.py +++ b/alembic/versions/359caaf8c5f1_initial.py @@ -1,8 +1,8 @@ """initial -Revision ID: 74ac90c019bf +Revision ID: 359caaf8c5f1 Revises: -Create Date: 2018-09-18 21:00:05.497858 +Create Date: 2018-09-20 10:25:44.438679 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. -revision = '74ac90c019bf' +revision = '359caaf8c5f1' down_revision = None branch_labels = None depends_on = None @@ -22,18 +22,22 @@ def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.create_table('attachments', - sa.Column('id', sa.Integer(), nullable=False), + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('filename', sa.String(), nullable=True), sa.Column('object_name', sa.String(), nullable=True), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('object_name') ) - op.create_table('pe_number', + op.create_table('pe_numbers', sa.Column('number', sa.String(), nullable=False), sa.Column('description', sa.String(), nullable=True), sa.PrimaryKeyConstraint('number') ) op.create_table('roles', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('name', sa.String(), nullable=True), sa.Column('description', sa.String(), nullable=True), @@ -42,8 +46,10 @@ def upgrade(): ) op.create_index(op.f('ix_roles_name'), 'roles', ['name'], unique=True) op.create_index(op.f('ix_roles_permissions'), 'roles', ['permissions'], unique=False) - op.create_table('task_order', - sa.Column('id', sa.Integer(), nullable=False), + op.create_table('task_orders', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('number', sa.String(), nullable=True), sa.Column('source', sa.Enum('MANUAL', 'EDA', name='source', native_enum=False), nullable=True), sa.Column('funding_type', sa.Enum('RDTE', 'OM', 'PROC', 'OTHER', name='fundingtype', native_enum=False), nullable=True), @@ -55,12 +61,14 @@ def upgrade(): sa.Column('clin_2001', sa.Integer(), nullable=True), sa.Column('clin_2003', sa.Integer(), nullable=True), sa.Column('expiration_date', sa.Date(), nullable=True), - sa.Column('attachment_id', sa.Integer(), nullable=True), + sa.Column('attachment_id', postgresql.UUID(as_uuid=True), nullable=True), sa.ForeignKeyConstraint(['attachment_id'], ['attachments.id'], ), sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('number') ) op.create_table('users', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('username', sa.String(), nullable=True), sa.Column('atat_role_id', postgresql.UUID(as_uuid=True), nullable=True), @@ -74,6 +82,8 @@ def upgrade(): sa.UniqueConstraint('email') ) op.create_table('request_reviews', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('comment', sa.String(), nullable=True), @@ -87,15 +97,18 @@ def upgrade(): sa.PrimaryKeyConstraint('id') ) op.create_table('requests', + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), - sa.Column('task_order_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['task_order_id'], ['task_order.id'], ), + sa.Column('task_order_id', postgresql.UUID(as_uuid=True), nullable=True), + sa.ForeignKeyConstraint(['task_order_id'], ['task_orders.id'], ), sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), sa.PrimaryKeyConstraint('id') ) op.create_table('request_internal_comments', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('text', sa.String(), nullable=True), sa.Column('user_id', postgresql.UUID(as_uuid=True), nullable=False), @@ -108,7 +121,6 @@ def upgrade(): sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), - sa.Column('name', sa.String(), nullable=True), sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=False), sa.Column('sequence', sa.BigInteger(), nullable=False), sa.Column('am_poc', sa.Boolean(), nullable=True), @@ -133,6 +145,7 @@ def upgrade(): sa.Column('average_daily_traffic_gb', sa.Integer(), nullable=True), sa.Column('rationalization_software_systems', sa.String(), nullable=True), sa.Column('organization_providing_assistance', sa.String(), nullable=True), + sa.Column('name', sa.String(), nullable=True), sa.Column('citizenship', sa.String(), nullable=True), sa.Column('designation', sa.String(), nullable=True), sa.Column('phone_number', sa.String(), nullable=True), @@ -178,19 +191,22 @@ def upgrade(): sa.PrimaryKeyConstraint('id') ) op.create_table('request_status_events', + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('new_status', sa.Enum('STARTED', 'SUBMITTED', 'PENDING_FINANCIAL_VERIFICATION', 'PENDING_CCPO_ACCEPTANCE', 'PENDING_CCPO_APPROVAL', 'CHANGES_REQUESTED', 'CHANGES_REQUESTED_TO_FINVER', 'APPROVED', 'EXPIRED', 'DELETED', name='requeststatus', native_enum=False), nullable=True), sa.Column('time_created', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True), sa.Column('request_id', postgresql.UUID(as_uuid=True), nullable=True), sa.Column('sequence', sa.BigInteger(), nullable=False), sa.Column('request_revision_id', postgresql.UUID(as_uuid=True), nullable=False), - sa.Column('request_review_id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=True), + sa.Column('request_review_id', postgresql.UUID(as_uuid=True), nullable=True), sa.ForeignKeyConstraint(['request_id'], ['requests.id'], ondelete='CASCADE'), sa.ForeignKeyConstraint(['request_review_id'], ['request_reviews.id'], ), sa.ForeignKeyConstraint(['request_revision_id'], ['request_revisions.id'], ), sa.PrimaryKeyConstraint('id') ) - op.create_table('workspace_role', + op.create_table('workspace_roles', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('workspace_id', postgresql.UUID(as_uuid=True), nullable=True), sa.Column('role_id', postgresql.UUID(as_uuid=True), nullable=True), @@ -200,9 +216,9 @@ def upgrade(): sa.ForeignKeyConstraint(['workspace_id'], ['workspaces.id'], ), sa.PrimaryKeyConstraint('id') ) - op.create_index(op.f('ix_workspace_role_user_id'), 'workspace_role', ['user_id'], unique=False) - op.create_index(op.f('ix_workspace_role_workspace_id'), 'workspace_role', ['workspace_id'], unique=False) - op.create_index('workspace_role_user_workspace', 'workspace_role', ['user_id', 'workspace_id'], unique=True) + op.create_index(op.f('ix_workspace_roles_user_id'), 'workspace_roles', ['user_id'], unique=False) + op.create_index(op.f('ix_workspace_roles_workspace_id'), 'workspace_roles', ['workspace_id'], unique=False) + op.create_index('workspace_role_user_workspace', 'workspace_roles', ['user_id', 'workspace_id'], unique=True) op.create_table('environments', sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), @@ -213,6 +229,8 @@ def upgrade(): sa.PrimaryKeyConstraint('id') ) op.create_table('environment_roles', + sa.Column('time_created', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('time_updated', sa.TIMESTAMP(timezone=True), server_default=sa.text('now()'), nullable=False), sa.Column('id', postgresql.UUID(as_uuid=True), server_default=sa.text('uuid_generate_v4()'), nullable=False), sa.Column('environment_id', postgresql.UUID(as_uuid=True), nullable=True), sa.Column('role', sa.String(), nullable=True), @@ -237,10 +255,10 @@ def downgrade(): op.drop_index('environments_role_user_environment', table_name='environment_roles') op.drop_table('environment_roles') op.drop_table('environments') - op.drop_index('workspace_role_user_workspace', table_name='workspace_role') - op.drop_index(op.f('ix_workspace_role_workspace_id'), table_name='workspace_role') - op.drop_index(op.f('ix_workspace_role_user_id'), table_name='workspace_role') - op.drop_table('workspace_role') + op.drop_index('workspace_role_user_workspace', table_name='workspace_roles') + op.drop_index(op.f('ix_workspace_roles_workspace_id'), table_name='workspace_roles') + op.drop_index(op.f('ix_workspace_roles_user_id'), table_name='workspace_roles') + op.drop_table('workspace_roles') op.drop_table('request_status_events') op.drop_table('projects') op.drop_table('workspaces') @@ -249,11 +267,11 @@ def downgrade(): op.drop_table('requests') op.drop_table('request_reviews') op.drop_table('users') - op.drop_table('task_order') + op.drop_table('task_orders') op.drop_index(op.f('ix_roles_permissions'), table_name='roles') op.drop_index(op.f('ix_roles_name'), table_name='roles') op.drop_table('roles') - op.drop_table('pe_number') + op.drop_table('pe_numbers') op.drop_table('attachments') # ### end Alembic commands ### diff --git a/atst/models/attachment.py b/atst/models/attachment.py index 21d12af0..caf034dd 100644 --- a/atst/models/attachment.py +++ b/atst/models/attachment.py @@ -1,7 +1,7 @@ from sqlalchemy import Column, Integer, String from flask import current_app as app -from atst.models import Base +from atst.models import Base, types, mixins from atst.database import db from atst.uploader import UploadError @@ -10,10 +10,10 @@ class AttachmentError(Exception): pass -class Attachment(Base): +class Attachment(Base, mixins.TimestampsMixin): __tablename__ = "attachments" - id = Column(Integer, primary_key=True) + id = types.Id() filename = Column(String) object_name = Column(String, unique=True) diff --git a/atst/models/environment_role.py b/atst/models/environment_role.py index 7f36fe73..fa05514c 100644 --- a/atst/models/environment_role.py +++ b/atst/models/environment_role.py @@ -3,18 +3,17 @@ from sqlalchemy import Index, ForeignKey, Column, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship -from atst.models import Base -from .types import Id +from atst.models import Base, types, mixins class CSPRole(Enum): NONSENSE_ROLE = "nonesense_role" -class EnvironmentRole(Base): +class EnvironmentRole(Base, mixins.TimestampsMixin): __tablename__ = "environment_roles" - id = Id() + id = types.Id() environment_id = Column(UUID(as_uuid=True), ForeignKey("environments.id")) environment = relationship("Environment", backref="roles") diff --git a/atst/models/pe_number.py b/atst/models/pe_number.py index 8cb5a52f..45789f25 100644 --- a/atst/models/pe_number.py +++ b/atst/models/pe_number.py @@ -4,7 +4,7 @@ from atst.models import Base class PENumber(Base): - __tablename__ = "pe_number" + __tablename__ = "pe_numbers" number = Column(String, primary_key=True) description = Column(String) diff --git a/atst/models/request.py b/atst/models/request.py index d43e2c5f..d7d1f96c 100644 --- a/atst/models/request.py +++ b/atst/models/request.py @@ -2,8 +2,7 @@ from sqlalchemy import Column, func, ForeignKey from sqlalchemy.types import DateTime from sqlalchemy.orm import relationship -from atst.models import Base -from atst.models.types import Id +from atst.models import Base, types, mixins from atst.models.request_status_event import RequestStatus from atst.utils import first_or_none from atst.models.request_revision import RequestRevision @@ -25,10 +24,10 @@ def update_dict_with_properties(instance, body, top_level_key, properties): return body -class Request(Base): +class Request(Base, mixins.TimestampsMixin): __tablename__ = "requests" - id = Id() + id = types.Id() time_created = Column(DateTime(timezone=True), server_default=func.now()) status_events = relationship( "RequestStatusEvent", backref="request", order_by="RequestStatusEvent.sequence" @@ -39,7 +38,7 @@ class Request(Base): user_id = Column(ForeignKey("users.id"), nullable=False) creator = relationship("User", backref="owned_requests") - task_order_id = Column(ForeignKey("task_order.id")) + task_order_id = Column(ForeignKey("task_orders.id")) task_order = relationship("TaskOrder") revisions = relationship( diff --git a/atst/models/request_internal_comment.py b/atst/models/request_internal_comment.py index e42e56cd..a3d333ad 100644 --- a/atst/models/request_internal_comment.py +++ b/atst/models/request_internal_comment.py @@ -1,10 +1,10 @@ from sqlalchemy import Column, String, ForeignKey from sqlalchemy.orm import relationship -from atst.models import Base, types +from atst.models import Base, types, mixins -class RequestInternalComment(Base): +class RequestInternalComment(Base, mixins.TimestampsMixin): __tablename__ = "request_internal_comments" id = types.Id() diff --git a/atst/models/request_review.py b/atst/models/request_review.py index 20fa1ed4..c38832f7 100644 --- a/atst/models/request_review.py +++ b/atst/models/request_review.py @@ -1,13 +1,13 @@ -from sqlalchemy import Column, BigInteger, String, ForeignKey +from sqlalchemy import Column, String, ForeignKey from sqlalchemy.orm import relationship -from atst.models import Base +from atst.models import Base, mixins, types -class RequestReview(Base): +class RequestReview(Base, mixins.TimestampsMixin): __tablename__ = "request_reviews" - id = Column(BigInteger, primary_key=True) + id = types.Id() status = relationship("RequestStatusEvent", uselist=False, back_populates="review") user_id = Column(ForeignKey("users.id"), nullable=False) diff --git a/atst/models/request_status_event.py b/atst/models/request_status_event.py index d4e906ff..2b90e5e7 100644 --- a/atst/models/request_status_event.py +++ b/atst/models/request_status_event.py @@ -5,7 +5,7 @@ from sqlalchemy.types import DateTime, BigInteger from sqlalchemy.schema import Sequence from sqlalchemy.dialects.postgresql import UUID -from atst.models import Base +from atst.models import Base, mixins from atst.models.types import Id @@ -22,7 +22,7 @@ class RequestStatus(Enum): DELETED = "Deleted" -class RequestStatusEvent(Base): +class RequestStatusEvent(Base, mixins.TimestampsMixin): __tablename__ = "request_status_events" id = Id() diff --git a/atst/models/role.py b/atst/models/role.py index 8833d3e3..746f6a92 100644 --- a/atst/models/role.py +++ b/atst/models/role.py @@ -2,14 +2,13 @@ from sqlalchemy import String, Column from sqlalchemy.dialects.postgresql import ARRAY from sqlalchemy.orm.attributes import flag_modified -from atst.models import Base -from .types import Id +from atst.models import Base, types, mixins -class Role(Base): +class Role(Base, mixins.TimestampsMixin): __tablename__ = "roles" - id = Id() + id = types.Id() name = Column(String, index=True, unique=True) description = Column(String) permissions = Column(ARRAY(String), index=True, server_default="{}") diff --git a/atst/models/task_order.py b/atst/models/task_order.py index caf15a20..23ec6af1 100644 --- a/atst/models/task_order.py +++ b/atst/models/task_order.py @@ -3,7 +3,7 @@ from enum import Enum from sqlalchemy import Column, Integer, String, ForeignKey, Enum as SQLAEnum, Date from sqlalchemy.orm import relationship -from atst.models import Base +from atst.models import Base, types, mixins class Source(Enum): @@ -18,10 +18,10 @@ class FundingType(Enum): OTHER = "OTHER" -class TaskOrder(Base): - __tablename__ = "task_order" +class TaskOrder(Base, mixins.TimestampsMixin): + __tablename__ = "task_orders" - id = Column(Integer, primary_key=True) + id = types.Id() number = Column(String, unique=True) source = Column(SQLAEnum(Source, native_enum=False)) funding_type = Column(SQLAEnum(FundingType, native_enum=False)) diff --git a/atst/models/user.py b/atst/models/user.py index 02109f1e..e0fb06f7 100644 --- a/atst/models/user.py +++ b/atst/models/user.py @@ -2,15 +2,14 @@ from sqlalchemy import String, ForeignKey, Column from sqlalchemy.orm import relationship from sqlalchemy.dialects.postgresql import UUID -from atst.models import Base -from .types import Id +from atst.models import Base, types, mixins from atst.models.permissions import Permissions -class User(Base): +class User(Base, mixins.TimestampsMixin): __tablename__ = "users" - id = Id() + id = types.Id() username = Column(String) atat_role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id")) diff --git a/atst/models/workspace_role.py b/atst/models/workspace_role.py index be238866..9ac6fcb1 100644 --- a/atst/models/workspace_role.py +++ b/atst/models/workspace_role.py @@ -2,12 +2,12 @@ from sqlalchemy import Index, ForeignKey, Column from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship -from atst.models import Base +from atst.models import Base, mixins from .types import Id -class WorkspaceRole(Base): - __tablename__ = "workspace_role" +class WorkspaceRole(Base, mixins.TimestampsMixin): + __tablename__ = "workspace_roles" id = Id() workspace_id = Column(UUID(as_uuid=True), ForeignKey("workspaces.id"), index=True) diff --git a/tests/models/test_task_order.py b/tests/models/test_task_order.py index dd83a0ca..f95cf0d0 100644 --- a/tests/models/test_task_order.py +++ b/tests/models/test_task_order.py @@ -1,12 +1,11 @@ -from atst.models.task_order import TaskOrder - from tests.factories import TaskOrderFactory +from tests.assert_util import dict_contains def test_as_dictionary(): data = TaskOrderFactory.dictionary() real_task_order = TaskOrderFactory.create(**data) - assert real_task_order.to_dictionary() == data + assert dict_contains(real_task_order.to_dictionary(), data) def test_budget():