Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert install_model to declarative mapping #12756

Merged
merged 23 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e2c7403
Rename mapping test, add install_model_mapping test
jdavcs Oct 19, 2021
fb7f71a
Add unit tests for install_model mapping
jdavcs Oct 20, 2021
6f45f26
Setup install_model for remapping
jdavcs Oct 20, 2021
29e1885
Add nonstandard test for ToolVersion relationships
jdavcs Oct 20, 2021
8f79a8f
Remove MigrateTools from model and mapping (note)
jdavcs Oct 20, 2021
86a30bc
Map RepositoryRepositoryDependencyAssociation declaratively
jdavcs Oct 20, 2021
a3d7a37
Map RepositoryDependency declaratively
jdavcs Oct 20, 2021
92b32ba
Map ToolDependency declaratively
jdavcs Oct 20, 2021
1fe5e6d
Map ToolVersion declaratively
jdavcs Oct 20, 2021
191464f
Map ToolVersionAssociation declaratively
jdavcs Oct 20, 2021
19dc5c9
Remove backref from ToolShedRepository.tool_version
jdavcs Oct 20, 2021
f99a397
Remove backref from ToolShedRepository.tool_dependencies
jdavcs Oct 20, 2021
cf96467
Remove unnecessary primary_join attr
jdavcs Oct 20, 2021
a8e3c84
Fix SAWarning: add back_populates args
jdavcs Oct 20, 2021
b0446b1
Drop redundant datatypes from fkeys
jdavcs Oct 20, 2021
353ce42
Drop redundant model constructors
jdavcs Oct 20, 2021
3738c1a
Add missing delete-from-db statement
jdavcs Oct 20, 2021
638f9a7
Fix import error
jdavcs Oct 20, 2021
d870278
Map ToolShedRepository declaratively (see note)
jdavcs Oct 20, 2021
691a3f6
Remove refs to ToolShedRepository.metadata in test/
jdavcs Oct 20, 2021
5acbb14
Remove refs to ToolShedRepository.metadata in scripts/
jdavcs Oct 20, 2021
bd765b0
Replace all remaining instances of TSR.metadata
jdavcs Oct 20, 2021
404bac3
Fix .metadata_ in tool_shed dir
jdavcs Oct 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 126 additions & 41 deletions lib/galaxy/model/tool_shed_install/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,81 @@
from enum import Enum
from typing import TYPE_CHECKING

from sqlalchemy import (
Boolean,
Column,
DateTime,
ForeignKey,
Integer,
String,
Table,
TEXT,
)
from sqlalchemy.orm import (
registry,
relationship,
)
from sqlalchemy.orm.decl_api import DeclarativeMeta

from galaxy.model.custom_types import (
MutableJSONType,
TrimmedString
)
from galaxy.model.orm.now import now
from galaxy.util import asbool
from galaxy.util.bunch import Bunch
from galaxy.util.dictifiable import Dictifiable
from galaxy.util.tool_shed import common_util

log = logging.getLogger(__name__)

mapper_registry = registry()

if TYPE_CHECKING:
from sqlalchemy.schema import Table

class _HasTable:
table: Table
else:
_HasTable = object


class ToolShedRepository(_HasTable):
class Base(metaclass=DeclarativeMeta):
__abstract__ = True
registry = mapper_registry
metadata = mapper_registry.metadata
__init__ = mapper_registry.constructor

@classmethod
def __declare_last__(cls):
cls.table = cls.__table__


class ToolShedRepository(Base, _HasTable):
__tablename__ = 'tool_shed_repository'

id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
tool_shed = Column(TrimmedString(255), index=True)
name = Column(TrimmedString(255), index=True)
description = Column(TEXT)
owner = Column(TrimmedString(255), index=True)
installed_changeset_revision = Column(TrimmedString(255))
changeset_revision = Column(TrimmedString(255), index=True)
ctx_rev = Column(TrimmedString(10))
metadata_ = Column('metadata', MutableJSONType, nullable=True)
includes_datatypes = Column(Boolean, index=True, default=False)
tool_shed_status = Column(MutableJSONType, nullable=True)
deleted = Column(Boolean, index=True, default=False)
uninstalled = Column(Boolean, default=False)
dist_to_shed = Column(Boolean, default=False)
status = Column(TrimmedString(255))
error_message = Column(TEXT)
tool_versions = relationship('ToolVersion', back_populates='tool_shed_repository')
tool_dependencies = relationship('ToolDependency', order_by='ToolDependency.name',
back_populates='tool_shed_repository')
required_repositories = relationship('RepositoryRepositoryDependencyAssociation',
back_populates='repository')

dict_collection_visible_keys = ['id', 'tool_shed', 'name', 'owner', 'installed_changeset_revision', 'changeset_revision', 'ctx_rev', 'includes_datatypes',
'tool_shed_status', 'deleted', 'uninstalled', 'dist_to_shed', 'status', 'error_message', 'description']
dict_element_visible_keys = ['id', 'tool_shed', 'name', 'owner', 'installed_changeset_revision', 'changeset_revision', 'ctx_rev', 'includes_datatypes',
Expand All @@ -46,7 +103,7 @@ class states(str, Enum):
UNINSTALLED = 'deleted_new'

def __init__(self, id=None, create_time=None, tool_shed=None, name=None, description=None, owner=None, installed_changeset_revision=None,
changeset_revision=None, ctx_rev=None, metadata=None, includes_datatypes=False, tool_shed_status=None, deleted=False,
changeset_revision=None, ctx_rev=None, metadata_=None, includes_datatypes=False, tool_shed_status=None, deleted=False,
uninstalled=False, dist_to_shed=False, status=None, error_message=None):
self.id = id
self.create_time = create_time
Expand All @@ -57,7 +114,7 @@ def __init__(self, id=None, create_time=None, tool_shed=None, name=None, descrip
self.installed_changeset_revision = installed_changeset_revision
self.changeset_revision = changeset_revision
self.ctx_rev = ctx_rev
self.metadata = metadata or {}
self.metadata_ = metadata_ or {}
self.includes_datatypes = includes_datatypes
self.tool_shed_status = tool_shed_status
self.deleted = deleted
Expand Down Expand Up @@ -96,11 +153,11 @@ def get_sharable_url(self, app):

@property
def shed_config_filename(self):
return self.metadata.get('shed_config_filename')
return self.metadata_.get('shed_config_filename')

@shed_config_filename.setter
def shed_config_filename(self, value):
self.metadata['shed_config_filename'] = os.path.abspath(value)
self.metadata_['shed_config_filename'] = os.path.abspath(value)

def get_shed_config_dict(self, app):
"""
Expand All @@ -125,7 +182,7 @@ def get_tool_relative_path(self, app):

def guess_shed_config(self, app):
tool_ids = []
for tool in self.metadata.get('tools', []):
for tool in self.metadata_.get('tools', []):
tool_ids.append(tool.get('guid'))
for shed_tool_conf_dict in app.toolbox.dynamic_confs(include_migrated_tool_conf=True):
name = shed_tool_conf_dict['config_filename']
Expand Down Expand Up @@ -158,11 +215,11 @@ def guess_shed_config(self, app):

@property
def has_readme_files(self):
return 'readme_files' in self.metadata
return 'readme_files' in self.metadata_

@property
def has_repository_dependencies(self):
repository_dependencies_dict = self.metadata.get('repository_dependencies', {})
repository_dependencies_dict = self.metadata_.get('repository_dependencies', {})
repository_dependencies = repository_dependencies_dict.get('repository_dependencies', [])
# [["http://localhost:9009", "package_libgtextutils_0_6", "test", "e2003cbf18cd", "True", "True"]]
for rd_tup in repository_dependencies:
Expand All @@ -174,7 +231,7 @@ def has_repository_dependencies(self):

@property
def has_repository_dependencies_only_if_compiling_contained_td(self):
repository_dependencies_dict = self.metadata.get('repository_dependencies', {})
repository_dependencies_dict = self.metadata_.get('repository_dependencies', {})
repository_dependencies = repository_dependencies_dict.get('repository_dependencies', [])
# [["http://localhost:9009", "package_libgtextutils_0_6", "test", "e2003cbf18cd", "True", "True"]]
for rd_tup in repository_dependencies:
Expand All @@ -190,28 +247,28 @@ def in_error_state(self):

@property
def includes_data_managers(self):
return bool(len(self.metadata.get('data_manager', {}).get('data_managers', {})))
return bool(len(self.metadata_.get('data_manager', {}).get('data_managers', {})))

@property
def includes_tools(self):
return 'tools' in self.metadata
return 'tools' in self.metadata_

@property
def includes_tools_for_display_in_tool_panel(self):
if self.includes_tools:
tool_dicts = self.metadata['tools']
tool_dicts = self.metadata_['tools']
for tool_dict in tool_dicts:
if tool_dict.get('add_to_tool_panel', True):
return True
return False

@property
def includes_tool_dependencies(self):
return 'tool_dependencies' in self.metadata
return 'tool_dependencies' in self.metadata_

@property
def includes_workflows(self):
return 'workflows' in self.metadata
return 'workflows' in self.metadata_

@property
def installed_repository_dependencies(self):
Expand Down Expand Up @@ -350,7 +407,7 @@ def requires_prior_installation_of(self):
"""
required_rd_tups_that_must_be_installed = []
if self.has_repository_dependencies:
rd_tups = self.metadata['repository_dependencies']['repository_dependencies']
rd_tups = self.metadata_['repository_dependencies']['repository_dependencies']
for rd_tup in rd_tups:
if len(rd_tup) == 5:
tool_shed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
Expand Down Expand Up @@ -447,7 +504,7 @@ def tuples_of_repository_dependencies_needed_for_compiling_td(self):
dependencies.
"""
rd_tups_of_repositories_needed_for_compiling_td = []
repository_dependencies = self.metadata.get('repository_dependencies', {})
repository_dependencies = self.metadata_.get('repository_dependencies', {})
rd_tups = repository_dependencies.get('repository_dependencies', [])
for rd_tup in rd_tups:
if len(rd_tup) == 6:
Expand Down Expand Up @@ -484,20 +541,49 @@ def upgrade_available(self):
return False


class RepositoryRepositoryDependencyAssociation(_HasTable):
class RepositoryRepositoryDependencyAssociation(Base, _HasTable):
__tablename__ = 'repository_repository_dependency_association'

id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
tool_shed_repository_id = Column(ForeignKey('tool_shed_repository.id'), index=True)
repository_dependency_id = Column(ForeignKey('repository_dependency.id'), index=True)
repository = relationship('ToolShedRepository', back_populates='required_repositories')
repository_dependency = relationship('RepositoryDependency')

def __init__(self, tool_shed_repository_id=None, repository_dependency_id=None):
self.tool_shed_repository_id = tool_shed_repository_id
self.repository_dependency_id = repository_dependency_id


class RepositoryDependency(_HasTable):
class RepositoryDependency(Base, _HasTable):
__tablename__ = 'repository_dependency'

id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
tool_shed_repository_id = Column(ForeignKey('tool_shed_repository.id'), index=True, nullable=False)
repository = relationship('ToolShedRepository')

def __init__(self, tool_shed_repository_id=None):
self.tool_shed_repository_id = tool_shed_repository_id


class ToolDependency(_HasTable):
class ToolDependency(Base, _HasTable):
__tablename__ = 'tool_dependency'

id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
tool_shed_repository_id = Column(ForeignKey('tool_shed_repository.id'), index=True, nullable=False)
name = Column(TrimmedString(255))
version = Column(TEXT)
type = Column(TrimmedString(40))
status = Column(TrimmedString(255), nullable=False)
error_message = Column(TEXT)
tool_shed_repository = relationship('ToolShedRepository', back_populates='tool_dependencies')

# converting this one to Enum breaks the tool shed tests,
# don't know why though -John
installation_status = Bunch(NEVER_INSTALLED='Never installed',
Expand Down Expand Up @@ -568,14 +654,21 @@ def is_installed(self):
return self.status == self.installation_status.INSTALLED


class ToolVersion(Dictifiable, _HasTable):
dict_element_visible_keys = ['id', 'tool_shed_repository']
class ToolVersion(Base, Dictifiable, _HasTable):
__tablename__ = 'tool_version'

def __init__(self, id=None, create_time=None, tool_id=None, tool_shed_repository=None):
self.id = id
self.create_time = create_time
self.tool_id = tool_id
self.tool_shed_repository = tool_shed_repository
id = Column(Integer, primary_key=True)
create_time = Column(DateTime, default=now)
update_time = Column(DateTime, default=now, onupdate=now)
tool_id = Column(String(255))
tool_shed_repository_id = Column(ForeignKey('tool_shed_repository.id'), index=True, nullable=True)
parent_tool_association = relationship('ToolVersionAssociation',
primaryjoin=(lambda: ToolVersion.id == ToolVersionAssociation.tool_id)) # type: ignore
child_tool_association = relationship('ToolVersionAssociation',
primaryjoin=(lambda: ToolVersion.id == ToolVersionAssociation.parent_id)) # type: ignore
tool_shed_repository = relationship('ToolShedRepository', back_populates='tool_versions')

dict_element_visible_keys = ['id', 'tool_shed_repository']

def to_dict(self, view='element'):
rval = super().to_dict(view=view)
Expand All @@ -587,17 +680,9 @@ def to_dict(self, view='element'):
return rval


class ToolVersionAssociation(_HasTable):

def __init__(self, id=None, tool_id=None, parent_id=None):
self.id = id
self.tool_id = tool_id
self.parent_id = parent_id

class ToolVersionAssociation(Base, _HasTable):
__tablename__ = 'tool_version_association'

class MigrateTools(_HasTable):

def __init__(self, repository_id=None, repository_path=None, version=None):
self.repository_id = repository_id
self.repository_path = repository_path
self.version = version
id = Column(Integer, primary_key=True)
tool_id = Column(ForeignKey('tool_version.id'), index=True, nullable=False)
parent_id = Column(ForeignKey('tool_version.id'), index=True, nullable=False)
Loading