Skip to content

Commit

Permalink
Promote resource to a top-level entity
Browse files Browse the repository at this point in the history
  • Loading branch information
marksparkza committed Dec 4, 2023
1 parent e4e8e7a commit a2e2481
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 118 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
"""Create archive and package entities
"""Create archive, resource and package entities
Revision ID: 220060b4adb3
Revision ID: 002ebdb598a3
Revises: df57d06e1ee5
Create Date: 2023-11-20 14:59:44.964701
Create Date: 2023-12-04 09:21:03.086156
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '220060b4adb3'
revision = '002ebdb598a3'
down_revision = 'df57d06e1ee5'
branch_labels = None
depends_on = None
Expand All @@ -23,42 +23,43 @@ def upgrade():
sa.Column('url', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('archive_resource',
op.create_table('resource',
sa.Column('id', sa.String(), nullable=False),
sa.Column('key', sa.String(), nullable=False),
sa.Column('path', sa.String(), nullable=True),
sa.Column('type', sa.Enum('file', 'folder', 'webpage', name='resourcetype'), nullable=False),
sa.Column('path', sa.String(), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('type', sa.String(), nullable=True),
sa.Column('size', sa.Integer(), nullable=True),
sa.Column('size', sa.BigInteger(), nullable=True),
sa.Column('md5', sa.String(), nullable=True),
sa.Column('timestamp', sa.TIMESTAMP(timezone=True), nullable=True),
sa.Column('archive_id', sa.String(), nullable=False),
sa.ForeignKeyConstraint(['archive_id'], ['archive.id'], ondelete='CASCADE'),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('archive_id', 'key', name='uix_archive_resource_archive_id_key')
sa.PrimaryKeyConstraint('id')
)
op.create_table('package',
sa.Column('id', sa.String(), nullable=False),
sa.Column('metadata_', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('timestamp', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('provider_id', sa.String(), nullable=False),
sa.Column('record_id', sa.String(), nullable=True),
sa.ForeignKeyConstraint(['provider_id'], ['provider.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['record_id'], ['record.id'], ondelete='SET NULL'),
sa.PrimaryKeyConstraint('id')
)
op.create_table('package_resource',
sa.Column('package_id', sa.String(), nullable=False),
sa.Column('resource_id', sa.String(), nullable=False),
sa.ForeignKeyConstraint(['package_id'], ['package.id'], ondelete='CASCADE'),
sa.ForeignKeyConstraint(['resource_id'], ['archive_resource.id'], ondelete='RESTRICT'),
sa.ForeignKeyConstraint(['resource_id'], ['resource.id'], ondelete='RESTRICT'),
sa.PrimaryKeyConstraint('package_id', 'resource_id')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic ###
# ### commands auto generated by Alembic - added drop type ###
op.drop_table('package_resource')
op.drop_table('package')
op.drop_table('archive_resource')
op.drop_table('resource')
op.drop_table('archive')
op.execute('drop type resourcetype')
# ### end Alembic commands ###
5 changes: 3 additions & 2 deletions odp/db/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from .archive import Archive, ArchiveResource
from .archive import Archive
from .catalog import Catalog, CatalogRecord, CatalogRecordFacet
from .client import Client, ClientCollection, ClientScope
from .collection import Collection, CollectionAudit, CollectionTag, CollectionTagAudit
from .package import Package, PackageResource
from .provider import Provider, ProviderAudit
from .record import PublishedRecord, Record, RecordAudit, RecordTag, RecordTagAudit
from .resource import Resource
from .role import Role, RoleCollection, RoleScope
from .schema import Schema
from .scope import Scope
from .tag import Tag
from .types import AuditCommand, IdentityCommand, SchemaType, ScopeType, TagCardinality, TagType
from .types import AuditCommand, IdentityCommand, ResourceType, SchemaType, ScopeType, TagCardinality, TagType
from .user import IdentityAudit, User, UserRole
from .vocabulary import Vocabulary, VocabularyTerm, VocabularyTermAudit
36 changes: 1 addition & 35 deletions odp/db/models/archive.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import uuid

from sqlalchemy import BigInteger, Column, ForeignKey, String, TIMESTAMP, UniqueConstraint
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String

from odp.db import Base

Expand All @@ -16,34 +13,3 @@ class Archive(Base):
url = Column(String, nullable=False)

_repr_ = 'id', 'url'


class ArchiveResource(Base):
"""A reference to a file or dataset in an archive.
`key` is the archive's unique identifier for the resource.
`path`, if specified, is relative to `url` of the archive.
"""

__tablename__ = 'archive_resource'

__table_args__ = (
UniqueConstraint(
'archive_id', 'key',
name='uix_archive_resource_archive_id_key',
),
)

id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
key = Column(String, nullable=False)
path = Column(String)
name = Column(String)
type = Column(String)
size = Column(BigInteger)
md5 = Column(String)
timestamp = Column(TIMESTAMP(timezone=True))

archive_id = Column(String, ForeignKey('archive.id', ondelete='CASCADE'), nullable=False)
archive = relationship('Archive')

_repr_ = 'id', 'key', 'path', 'name', 'type', 'size', 'archive_id'
9 changes: 6 additions & 3 deletions odp/db/models/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ class Package(Base):

class PackageResource(Base):
"""Model of a many-to-many package-resource association,
representing the set of archived resources constituting a package."""
representing the set of resources constituting a package.
A resource cannot be deleted if it is part of a package.
"""

__tablename__ = 'package_resource'

package_id = Column(String, ForeignKey('package.id', ondelete='CASCADE'), primary_key=True)
resource_id = Column(String, ForeignKey('archive_resource.id', ondelete='RESTRICT'), primary_key=True)
resource_id = Column(String, ForeignKey('resource.id', ondelete='RESTRICT'), primary_key=True)

package = relationship('Package', viewonly=True)
resource = relationship('ArchiveResource', viewonly=True)
resource = relationship('Resource', viewonly=True)
29 changes: 29 additions & 0 deletions odp/db/models/resource.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import uuid

from sqlalchemy import BigInteger, Column, Enum, ForeignKey, String, TIMESTAMP
from sqlalchemy.orm import relationship

from odp.db import Base
from odp.db.models.types import ResourceType


class Resource(Base):
"""A reference to a file, folder or web page in an archive.
`path` is relative to `url` of the archive.
"""

__tablename__ = 'resource'

id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
type = Column(Enum(ResourceType), nullable=False)
path = Column(String, nullable=False)
name = Column(String)
size = Column(BigInteger)
md5 = Column(String)
timestamp = Column(TIMESTAMP(timezone=True))

archive_id = Column(String, ForeignKey('archive.id', ondelete='CASCADE'), nullable=False)
archive = relationship('Archive')

_repr_ = 'id', 'path', 'name', 'type', 'size', 'archive_id'
6 changes: 6 additions & 0 deletions odp/db/models/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ def __repr__(self):
return repr(self.value)


class ResourceType(DBEnum):
file = 'file'
folder = 'folder'
webpage = 'webpage'


class SchemaType(DBEnum):
metadata = 'metadata'
tag = 'tag'
Expand Down

0 comments on commit a2e2481

Please sign in to comment.