diff --git a/app/modules/dataset/models.py b/app/modules/dataset/models.py index 18120878..968d6d49 100644 --- a/app/modules/dataset/models.py +++ b/app/modules/dataset/models.py @@ -101,7 +101,8 @@ def get_file_total_size(self): return sum(file.size for fm in self.feature_models for file in fm.files) def get_file_total_size_for_human(self): - return get_human_readable_size(self.get_file_total_size()) + from app.modules.dataset.services import SizeService + return SizeService().get_human_readable_size(self.get_file_total_size()) def get_uvlhub_doi(self): from app.modules.dataset.services import DataSetService @@ -151,7 +152,8 @@ class File(db.Model): feature_model_id = db.Column(db.Integer, db.ForeignKey('feature_model.id'), nullable=False) def get_formatted_size(self): - return get_human_readable_size(self.size) + from app.modules.dataset.services import SizeService + return SizeService().get_human_readable_size(self.size) def to_dict(self): return { @@ -159,7 +161,7 @@ def to_dict(self): 'name': self.name, 'checksum': self.checksum, 'size_in_bytes': self.size, - 'size_in_human_format': get_human_readable_size(self.size), + 'size_in_human_format': self.get_formatted_size(), 'url': f'{request.host_url.rstrip("/")}/file/download/{self.id}', } @@ -248,12 +250,7 @@ def __repr__(self): ) -def get_human_readable_size(size): - if size < 1024: - return f'{size} bytes' - elif size < 1024 ** 2: - return f'{round(size / 1024, 2)} KB' - elif size < 1024 ** 3: - return f'{round(size / (1024 ** 2), 2)} MB' - else: - return f'{round(size / (1024 ** 3), 2)} GB' +class DOIMapping(db.Model): + id = db.Column(db.Integer, primary_key=True) + dataset_doi_old = db.Column(db.String(120)) + dataset_doi_new = db.Column(db.String(120)) diff --git a/app/modules/dataset/repositories.py b/app/modules/dataset/repositories.py index 833ab94b..dbbef633 100644 --- a/app/modules/dataset/repositories.py +++ b/app/modules/dataset/repositories.py @@ -1,4 +1,6 @@ +from datetime import datetime, timezone import re +from flask_login import current_user import unidecode from typing import Optional @@ -6,6 +8,7 @@ from app.modules.dataset.models import ( Author, + DOIMapping, DSDownloadRecord, DSMetaData, DSViewRecord, @@ -50,6 +53,21 @@ def total_dataset_views(self) -> int: max_id = self.model.query.with_entities(func.max(self.model.id)).scalar() return max_id if max_id is not None else 0 + def the_record_exists(self, dataset: DataSet, user_cookie: str): + return self.model.query.filter_by( + user_id=current_user.id if current_user.is_authenticated else None, + dataset_id=dataset.id, + view_cookie=user_cookie + ).first() + + def create_new_record(self, dataset: DataSet, user_cookie: str) -> DSViewRecord: + return self.create( + user_id=current_user.id if current_user.is_authenticated else None, + dataset_id=dataset.id, + view_date=datetime.now(timezone.utc), + view_cookie=user_cookie, + ) + class DataSetRepository(BaseRepository): def __init__(self): @@ -175,3 +193,11 @@ def __init__(self): def total_feature_model_views(self) -> int: max_id = self.model.query.with_entities(func.max(self.model.id)).scalar() return max_id if max_id is not None else 0 + + +class DOIMappingRepository(BaseRepository): + def __init__(self): + super().__init__(DOIMapping) + + def get_new_doi(self, old_doi: str) -> str: + return self.model.query.filter_by(dataset_doi_old=old_doi).first() diff --git a/app/modules/dataset/routes.py b/app/modules/dataset/routes.py index aad230f6..1bf202c7 100644 --- a/app/modules/dataset/routes.py +++ b/app/modules/dataset/routes.py @@ -11,6 +11,7 @@ from core.configuration.configuration import uploads_folder_name from flask import ( + redirect, render_template, request, jsonify, @@ -18,13 +19,13 @@ current_app, make_response, abort, + url_for, ) from flask_login import login_required, current_user from app.modules.dataset.forms import DataSetForm from app.modules.dataset.models import ( DSDownloadRecord, - DSViewRecord, DataSet, File, FileDownloadRecord, @@ -42,6 +43,7 @@ FeatureModelService, FileService, FileDownloadRecordService, + DOIMappingService ) from app.modules.zenodo.services import ZenodoService @@ -50,6 +52,8 @@ author_service = AuthorService() dsmetadata_service = DSMetaDataService() zenodo_service = ZenodoService() +doi_mapping_service = DOIMappingService() +ds_view_record_service = DSViewRecordService() @dataset_bp.route("/dataset/upload", methods=["GET", "POST"]) @@ -480,35 +484,23 @@ def view_file(file_id): @dataset_bp.route("/doi//", methods=["GET"]) def subdomain_index(doi): + # Check if the DOI is an old DOI + new_doi = doi_mapping_service.get_new_doi(doi) + if new_doi: + # Redirect to the same path with the new DOI + return redirect(url_for('dataset.subdomain_index', doi=new_doi), code=302) + + # Try to search the dataset by the provided DOI (which should already be the new one) ds_meta_data = dsmetadata_service.filter_by_doi(doi) if not ds_meta_data: abort(404) + # Get dataset dataset = ds_meta_data.data_set - # Get the cookie from the request or generate a new one if it does not exist - user_cookie = request.cookies.get("view_cookie") - if not user_cookie: - user_cookie = str(uuid.uuid4()) - - # Check if the view record already exists for this cookie - existing_record = DSViewRecord.query.filter_by( - user_id=current_user.id if current_user.is_authenticated else None, - dataset_id=dataset.id, - view_cookie=user_cookie - ).first() - - if not existing_record: - # Record the view in your database - DSViewRecordService().create( - user_id=current_user.id if current_user.is_authenticated else None, - dataset_id=dataset.id, - view_date=datetime.now(timezone.utc), - view_cookie=user_cookie, - ) - # Save the cookie to the user's browser + user_cookie = ds_view_record_service.create_cookie(dataset=dataset) resp = make_response(render_template("dataset/view_dataset.html", dataset=dataset)) resp.set_cookie("view_cookie", user_cookie) diff --git a/app/modules/dataset/services.py b/app/modules/dataset/services.py index 25a185c8..1a08efd6 100644 --- a/app/modules/dataset/services.py +++ b/app/modules/dataset/services.py @@ -1,9 +1,13 @@ import os from typing import Optional +import uuid -from app.modules.dataset.models import DataSet, DSMetaData +from flask import request + +from app.modules.dataset.models import DSViewRecord, DataSet, DSMetaData from app.modules.dataset.repositories import ( AuthorRepository, + DOIMappingRepository, DSDownloadRecordRepository, DSMetaDataRepository, DSViewRecordRepository, @@ -98,11 +102,6 @@ def filter_by_doi(self, doi: str) -> Optional[DSMetaData]: return self.repository.filter_by_doi(doi) -class DSViewRecordService(BaseService): - def __init__(self): - super().__init__(DSViewRecordRepository()) - - class FMMetaDataService(BaseService): def __init__(self): super().__init__(FMMetaDataRepository()) @@ -116,3 +115,55 @@ def __init__(self): class FileDownloadRecordService(BaseService): def __init__(self): super().__init__(FileDownloadRecordRepository()) + + +class DOIMappingService(BaseService): + def __init__(self): + super().__init__(DOIMappingRepository()) + + def get_new_doi(self, old_doi: str) -> str: + doi_mapping = self.repository.get_new_doi(old_doi) + if doi_mapping: + return doi_mapping.dataset_doi_new + else: + return None + + +class DSViewRecordService(BaseService): + def __init__(self): + super().__init__(DSViewRecordRepository()) + + def the_record_exists(self, dataset: DataSet, user_cookie: str): + return self.repository.the_record_exists(dataset, user_cookie) + + def create_new_record(self, dataset: DataSet, user_cookie: str) -> DSViewRecord: + return self.repository.create_new_record(dataset, user_cookie) + + def create_cookie(self, dataset: DataSet) -> str: + + user_cookie = request.cookies.get("view_cookie") + if not user_cookie: + user_cookie = str(uuid.uuid4()) + + existing_record = self.the_record_exists(dataset=dataset, user_cookie=user_cookie) + + if not existing_record: + self.create_new_record(dataset=dataset, user_cookie=user_cookie) + + return user_cookie + + +class SizeService(): + + def __init__(self): + pass + + def get_human_readable_size(self, size: int) -> str: + if size < 1024: + return f'{size} bytes' + elif size < 1024 ** 2: + return f'{round(size / 1024, 2)} KB' + elif size < 1024 ** 3: + return f'{round(size / (1024 ** 2), 2)} MB' + else: + return f'{round(size / (1024 ** 3), 2)} GB' diff --git a/migrations/alembic.ini b/migrations/alembic.ini index ec9d45c2..d78ea557 100644 --- a/migrations/alembic.ini +++ b/migrations/alembic.ini @@ -8,7 +8,6 @@ # the 'revision' command, regardless of autogenerate # revision_environment = false - # Logging configuration [loggers] keys = root,sqlalchemy,alembic,flask_migrate diff --git a/migrations/versions/4ce46845a4b0_.py b/migrations/versions/4ce46845a4b0_.py new file mode 100644 index 00000000..860a86fc --- /dev/null +++ b/migrations/versions/4ce46845a4b0_.py @@ -0,0 +1,43 @@ +"""empty message + +Revision ID: 4ce46845a4b0 +Revises: +Create Date: 2024-07-08 12:38:55.095000 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '4ce46845a4b0' +down_revision = '97d142f05ca0' +branch_labels = None +depends_on = None + + +def upgrade(): + conn = op.get_bind() + inspector = sa.Inspector.from_engine(conn) + + if 'doi_mapping' not in inspector.get_table_names(): + op.create_table('doi_mapping', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('dataset_doi_old', sa.String(length=120), nullable=True), + sa.Column('dataset_doi_new', sa.String(length=120), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + + if 'webhook' not in inspector.get_table_names(): + op.create_table('webhook', + sa.Column('id', sa.Integer(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('webhook') + op.drop_table('doi_mapping') + # ### end Alembic commands ### diff --git a/migrations/versions/97d142f05ca0_.py b/migrations/versions/97d142f05ca0_.py index d314dcde..8bad9c99 100644 --- a/migrations/versions/97d142f05ca0_.py +++ b/migrations/versions/97d142f05ca0_.py @@ -17,146 +17,191 @@ def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table('ds_metrics', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('number_of_models', sa.String(length=120), nullable=True), - sa.Column('number_of_features', sa.String(length=120), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('fm_metrics', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('solver', sa.Text(), nullable=True), - sa.Column('not_solver', sa.Text(), nullable=True), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('user', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('email', sa.String(length=256), nullable=False), - sa.Column('password', sa.String(length=256), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=False), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('email') - ) - op.create_table('zenodo', - sa.Column('id', sa.Integer(), nullable=False), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('ds_meta_data', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('deposition_id', sa.Integer(), nullable=True), - sa.Column('title', sa.String(length=120), nullable=False), - sa.Column('description', sa.Text(), nullable=False), - sa.Column('publication_type', sa.Enum('NONE', 'ANNOTATION_COLLECTION', 'BOOK', 'BOOK_SECTION', 'CONFERENCE_PAPER', 'DATA_MANAGEMENT_PLAN', 'JOURNAL_ARTICLE', 'PATENT', 'PREPRINT', 'PROJECT_DELIVERABLE', 'PROJECT_MILESTONE', 'PROPOSAL', 'REPORT', 'SOFTWARE_DOCUMENTATION', 'TAXONOMIC_TREATMENT', 'TECHNICAL_NOTE', 'THESIS', 'WORKING_PAPER', 'OTHER', name='publicationtype'), nullable=False), - sa.Column('publication_doi', sa.String(length=120), nullable=True), - sa.Column('dataset_doi', sa.String(length=120), nullable=True), - sa.Column('tags', sa.String(length=120), nullable=True), - sa.Column('ds_metrics_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['ds_metrics_id'], ['ds_metrics.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('fm_meta_data', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('uvl_filename', sa.String(length=120), nullable=False), - sa.Column('title', sa.String(length=120), nullable=False), - sa.Column('description', sa.Text(), nullable=False), - sa.Column('publication_type', sa.Enum('NONE', 'ANNOTATION_COLLECTION', 'BOOK', 'BOOK_SECTION', 'CONFERENCE_PAPER', 'DATA_MANAGEMENT_PLAN', 'JOURNAL_ARTICLE', 'PATENT', 'PREPRINT', 'PROJECT_DELIVERABLE', 'PROJECT_MILESTONE', 'PROPOSAL', 'REPORT', 'SOFTWARE_DOCUMENTATION', 'TAXONOMIC_TREATMENT', 'TECHNICAL_NOTE', 'THESIS', 'WORKING_PAPER', 'OTHER', name='publicationtype'), nullable=False), - sa.Column('publication_doi', sa.String(length=120), nullable=True), - sa.Column('tags', sa.String(length=120), nullable=True), - sa.Column('uvl_version', sa.String(length=120), nullable=True), - sa.Column('fm_metrics_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['fm_metrics_id'], ['fm_metrics.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('user_profile', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=False), - sa.Column('orcid', sa.String(length=19), nullable=True), - sa.Column('affiliation', sa.String(length=100), nullable=True), - sa.Column('name', sa.String(length=100), nullable=False), - sa.Column('surname', sa.String(length=100), nullable=False), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('user_id') - ) - op.create_table('author', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=120), nullable=False), - sa.Column('affiliation', sa.String(length=120), nullable=True), - sa.Column('orcid', sa.String(length=120), nullable=True), - sa.Column('ds_meta_data_id', sa.Integer(), nullable=True), - sa.Column('fm_meta_data_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['ds_meta_data_id'], ['ds_meta_data.id'], ), - sa.ForeignKeyConstraint(['fm_meta_data_id'], ['fm_meta_data.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('data_set', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=False), - sa.Column('ds_meta_data_id', sa.Integer(), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=False), - sa.ForeignKeyConstraint(['ds_meta_data_id'], ['ds_meta_data.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('ds_download_record', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('dataset_id', sa.Integer(), nullable=True), - sa.Column('download_date', sa.DateTime(), nullable=False), - sa.Column('download_cookie', sa.String(length=36), nullable=False), - sa.ForeignKeyConstraint(['dataset_id'], ['data_set.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('ds_view_record', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('dataset_id', sa.Integer(), nullable=True), - sa.Column('view_date', sa.DateTime(), nullable=False), - sa.Column('view_cookie', sa.String(length=36), nullable=False), - sa.ForeignKeyConstraint(['dataset_id'], ['data_set.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('feature_model', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('data_set_id', sa.Integer(), nullable=False), - sa.Column('fm_meta_data_id', sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(['data_set_id'], ['data_set.id'], ), - sa.ForeignKeyConstraint(['fm_meta_data_id'], ['fm_meta_data.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('file', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('name', sa.String(length=120), nullable=False), - sa.Column('checksum', sa.String(length=120), nullable=False), - sa.Column('size', sa.Integer(), nullable=False), - sa.Column('feature_model_id', sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(['feature_model_id'], ['feature_model.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('file_download_record', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('file_id', sa.Integer(), nullable=True), - sa.Column('download_date', sa.DateTime(), nullable=False), - sa.Column('download_cookie', sa.String(length=36), nullable=False), - sa.ForeignKeyConstraint(['file_id'], ['file.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - op.create_table('file_view_record', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user_id', sa.Integer(), nullable=True), - sa.Column('file_id', sa.Integer(), nullable=False), - sa.Column('view_date', sa.DateTime(), nullable=True), - sa.Column('view_cookie', sa.String(length=36), nullable=True), - sa.ForeignKeyConstraint(['file_id'], ['file.id'], ), - sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), - sa.PrimaryKeyConstraint('id') - ) - # ### end Alembic commands ### + conn = op.get_bind() + inspector = sa.Inspector.from_engine(conn) + + if 'ds_metrics' not in inspector.get_table_names(): + op.create_table( + 'ds_metrics', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('number_of_models', sa.String(length=120), nullable=True), + sa.Column('number_of_features', sa.String(length=120), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + + if 'fm_metrics' not in inspector.get_table_names(): + op.create_table( + 'fm_metrics', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('solver', sa.Text(), nullable=True), + sa.Column('not_solver', sa.Text(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + + if 'user' not in inspector.get_table_names(): + op.create_table( + 'user', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('email', sa.String(length=256), nullable=False), + sa.Column('password', sa.String(length=256), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('email') + ) + + if 'zenodo' not in inspector.get_table_names(): + op.create_table( + 'zenodo', + sa.Column('id', sa.Integer(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + + if 'ds_meta_data' not in inspector.get_table_names(): + op.create_table( + 'ds_meta_data', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('deposition_id', sa.Integer(), nullable=True), + sa.Column('title', sa.String(length=120), nullable=False), + sa.Column('description', sa.Text(), nullable=False), + sa.Column('publication_type', sa.Enum('NONE', 'ANNOTATION_COLLECTION', 'BOOK', 'BOOK_SECTION', 'CONFERENCE_PAPER', 'DATA_MANAGEMENT_PLAN', 'JOURNAL_ARTICLE', 'PATENT', 'PREPRINT', 'PROJECT_DELIVERABLE', 'PROJECT_MILESTONE', 'PROPOSAL', 'REPORT', 'SOFTWARE_DOCUMENTATION', 'TAXONOMIC_TREATMENT', 'TECHNICAL_NOTE', 'THESIS', 'WORKING_PAPER', 'OTHER', name='publicationtype'), nullable=False), + sa.Column('publication_doi', sa.String(length=120), nullable=True), + sa.Column('dataset_doi', sa.String(length=120), nullable=True), + sa.Column('tags', sa.String(length=120), nullable=True), + sa.Column('ds_metrics_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['ds_metrics_id'], ['ds_metrics.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'fm_meta_data' not in inspector.get_table_names(): + op.create_table( + 'fm_meta_data', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('uvl_filename', sa.String(length=120), nullable=False), + sa.Column('title', sa.String(length=120), nullable=False), + sa.Column('description', sa.Text(), nullable=False), + sa.Column('publication_type', sa.Enum('NONE', 'ANNOTATION_COLLECTION', 'BOOK', 'BOOK_SECTION', 'CONFERENCE_PAPER', 'DATA_MANAGEMENT_PLAN', 'JOURNAL_ARTICLE', 'PATENT', 'PREPRINT', 'PROJECT_DELIVERABLE', 'PROJECT_MILESTONE', 'PROPOSAL', 'REPORT', 'SOFTWARE_DOCUMENTATION', 'TAXONOMIC_TREATMENT', 'TECHNICAL_NOTE', 'THESIS', 'WORKING_PAPER', 'OTHER', name='publicationtype'), nullable=False), + sa.Column('publication_doi', sa.String(length=120), nullable=True), + sa.Column('tags', sa.String(length=120), nullable=True), + sa.Column('uvl_version', sa.String(length=120), nullable=True), + sa.Column('fm_metrics_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['fm_metrics_id'], ['fm_metrics.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'user_profile' not in inspector.get_table_names(): + op.create_table( + 'user_profile', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('orcid', sa.String(length=19), nullable=True), + sa.Column('affiliation', sa.String(length=100), nullable=True), + sa.Column('name', sa.String(length=100), nullable=False), + sa.Column('surname', sa.String(length=100), nullable=False), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user_id') + ) + + if 'author' not in inspector.get_table_names(): + op.create_table( + 'author', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=120), nullable=False), + sa.Column('affiliation', sa.String(length=120), nullable=True), + sa.Column('orcid', sa.String(length=120), nullable=True), + sa.Column('ds_meta_data_id', sa.Integer(), nullable=True), + sa.Column('fm_meta_data_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['ds_meta_data_id'], ['ds_meta_data.id'], ), + sa.ForeignKeyConstraint(['fm_meta_data_id'], ['fm_meta_data.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'data_set' not in inspector.get_table_names(): + op.create_table( + 'data_set', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=False), + sa.Column('ds_meta_data_id', sa.Integer(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['ds_meta_data_id'], ['ds_meta_data.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'ds_download_record' not in inspector.get_table_names(): + op.create_table( + 'ds_download_record', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('dataset_id', sa.Integer(), nullable=True), + sa.Column('download_date', sa.DateTime(), nullable=False), + sa.Column('download_cookie', sa.String(length=36), nullable=False), + sa.ForeignKeyConstraint(['dataset_id'], ['data_set.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'ds_view_record' not in inspector.get_table_names(): + op.create_table( + 'ds_view_record', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('dataset_id', sa.Integer(), nullable=True), + sa.Column('view_date', sa.DateTime(), nullable=False), + sa.Column('view_cookie', sa.String(length=36), nullable=False), + sa.ForeignKeyConstraint(['dataset_id'], ['data_set.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'feature_model' not in inspector.get_table_names(): + op.create_table( + 'feature_model', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('data_set_id', sa.Integer(), nullable=False), + sa.Column('fm_meta_data_id', sa.Integer(), nullable=True), + sa.ForeignKeyConstraint(['data_set_id'], ['data_set.id'], ), + sa.ForeignKeyConstraint(['fm_meta_data_id'], ['fm_meta_data.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'file' not in inspector.get_table_names(): + op.create_table( + 'file', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('name', sa.String(length=120), nullable=False), + sa.Column('checksum', sa.String(length=120), nullable=False), + sa.Column('size', sa.Integer(), nullable=False), + sa.Column('feature_model_id', sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(['feature_model_id'], ['feature_model.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'file_download_record' not in inspector.get_table_names(): + op.create_table( + 'file_download_record', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('file_id', sa.Integer(), nullable=True), + sa.Column('download_date', sa.DateTime(), nullable=False), + sa.Column('download_cookie', sa.String(length=36), nullable=False), + sa.ForeignKeyConstraint(['file_id'], ['file.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) + + if 'file_view_record' not in inspector.get_table_names(): + op.create_table( + 'file_view_record', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user_id', sa.Integer(), nullable=True), + sa.Column('file_id', sa.Integer(), nullable=False), + sa.Column('view_date', sa.DateTime(), nullable=True), + sa.Column('view_cookie', sa.String(length=36), nullable=True), + sa.ForeignKeyConstraint(['file_id'], ['file.id'], ), + sa.ForeignKeyConstraint(['user_id'], ['user.id'], ), + sa.PrimaryKeyConstraint('id') + ) def downgrade():