Skip to content

Commit

Permalink
Add archive and package entities
Browse files Browse the repository at this point in the history
  • Loading branch information
marksparkza committed Nov 20, 2023
1 parent 50043c9 commit f36c9d5
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 0 deletions.
Binary file modified ERD.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""Create archive and package entities
Revision ID: 220060b4adb3
Revises: df57d06e1ee5
Create Date: 2023-11-20 14:59:44.964701
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '220060b4adb3'
down_revision = 'df57d06e1ee5'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic ###
op.create_table('archive',
sa.Column('id', sa.String(), nullable=False),
sa.Column('url', sa.String(), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table('archive_resource',
sa.Column('id', sa.String(), nullable=False),
sa.Column('key', sa.String(), nullable=False),
sa.Column('path', sa.String(), nullable=True),
sa.Column('name', sa.String(), nullable=True),
sa.Column('type', sa.String(), nullable=True),
sa.Column('size', sa.Integer(), 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')
)
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('record_id', sa.String(), nullable=True),
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.PrimaryKeyConstraint('package_id', 'resource_id')
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic ###
op.drop_table('package_resource')
op.drop_table('package')
op.drop_table('archive_resource')
op.drop_table('archive')
# ### end Alembic commands ###
2 changes: 2 additions & 0 deletions odp/db/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from .archive import Archive, ArchiveResource
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 .role import Role, RoleCollection, RoleScope
Expand Down
49 changes: 49 additions & 0 deletions odp/db/models/archive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import uuid

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

from odp.db import Base


class Archive(Base):
"""An archive represents a data store that provides
long-term preservation of and access to digital resources."""

__tablename__ = 'archive'

id = Column(String, primary_key=True)
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(Integer)
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'
40 changes: 40 additions & 0 deletions odp/db/models/package.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import uuid

from sqlalchemy import Column, ForeignKey, String, TIMESTAMP
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship

from odp.db import Base


class Package(Base):
"""A package represents a set of resources that constitute
a digital object.
A package may include non-authoritative metadata, which can
be used when creating/updating the linked record.
"""

__tablename__ = 'package'

id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
metadata_ = Column(JSONB)
timestamp = Column(TIMESTAMP(timezone=True), nullable=False)

record_id = Column(String, ForeignKey('record.id', ondelete='SET NULL'))
record = relationship('Record')

_repr_ = 'id', 'record_id',


class PackageResource(Base):
"""Model of a many-to-many package-resource association,
representing the set of archived resources constituting 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)

package = relationship('Package', viewonly=True)
resource = relationship('ArchiveResource', viewonly=True)

0 comments on commit f36c9d5

Please sign in to comment.