From 936c8489b39209d0731c0bb9519d3a16d800e93f Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Fri, 26 Oct 2018 16:01:31 +0100 Subject: [PATCH] add TemplateFolder model a TemplateFolder has a service, a name, and a parent. Parent is a nullable foreign key pointing to another TemplateFolder instance. We don't do any checks here for cyclical or otherwise invalid folder structures so keep your data clean, folks! Unsurprisingly, a Template can be part of a TemplateFolder - there's a mapping class (template_folder_map to avoid giving it a dumb name) - this mapping table shouldn't be interacted with directly - rather, you should use the `Template.folder` or `TemplateFolder.templates` relationship. --- app/models.py | 28 ++++++++++++++ migrations/versions/0242_template_folders.py | 39 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 migrations/versions/0242_template_folders.py diff --git a/app/models.py b/app/models.py index 72a0e3f7d..f075c9f43 100644 --- a/app/models.py +++ b/app/models.py @@ -706,6 +706,27 @@ class TemplateProcessTypes(db.Model): name = db.Column(db.String(255), primary_key=True) +class TemplateFolder(db.Model): + __tablename__ = 'template_folder' + + id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), nullable=False) + name = db.Column(db.String, nullable=False) + parent_id = db.Column(UUID(as_uuid=True), db.ForeignKey('template_folder.id'), nullable=True) + + service = db.relationship('Service') + parent = db.relationship('TemplateFolder', remote_side=[id], backref='children') + + +template_folder_map = db.Table( + 'template_folder_map', + db.Model.metadata, + # template_id is a primary key as a template can only belong in one folder + db.Column('template_id', UUID(as_uuid=True), db.ForeignKey('templates.id'), primary_key=True, nullable=False), + db.Column('template_folder_id', UUID(as_uuid=True), db.ForeignKey('template_folder.id'), nullable=False), +) + + PRECOMPILED_TEMPLATE_NAME = 'Pre-compiled PDF' @@ -837,6 +858,13 @@ class Template(TemplateBase): service = db.relationship('Service', backref='templates') version = db.Column(db.Integer, default=0, nullable=False) + folder = db.relationship( + 'TemplateFolder', + secondary=template_folder_map, + uselist=False, + backref=db.backref('templates', lazy='dynamic') + ) + def get_link(self): # TODO: use "/v2/" route once available return url_for( diff --git a/migrations/versions/0242_template_folders.py b/migrations/versions/0242_template_folders.py new file mode 100644 index 000000000..187ae8ec5 --- /dev/null +++ b/migrations/versions/0242_template_folders.py @@ -0,0 +1,39 @@ +""" + +Revision ID: 0242_template_folders +Revises: 0241_another_letter_org +Create Date: 2018-10-26 16:00:40.173840 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +revision = '0242_template_folders' +down_revision = '0241_another_letter_org' + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('template_folder', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('service_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('parent_id', postgresql.UUID(as_uuid=True), nullable=True), + sa.ForeignKeyConstraint(['parent_id'], ['template_folder.id'], ), + sa.ForeignKeyConstraint(['service_id'], ['services.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('template_folder_map', + sa.Column('template_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('template_folder_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.ForeignKeyConstraint(['template_folder_id'], ['template_folder.id'], ), + sa.ForeignKeyConstraint(['template_id'], ['templates.id'], ), + sa.PrimaryKeyConstraint('template_id') + ) + + +def downgrade(): + op.drop_table('template_folder_map') + op.drop_table('template_folder') + # ### end Alembic commands ###