Skip to content

Commit

Permalink
Add scripts to fix association null values
Browse files Browse the repository at this point in the history
  • Loading branch information
jdavcs committed Sep 6, 2024
1 parent 8d65a5e commit c1a9264
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 3 deletions.
87 changes: 87 additions & 0 deletions lib/galaxy/model/scripts/association_table_fixer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import os
import sys
from abc import (
ABC,
abstractmethod,
)

from sqlalchemy import (
create_engine,
delete,
func,
null,
or_,
select,
)

from galaxy.model import (
Base,
GroupRoleAssociation,
UserGroupAssociation,
UserRoleAssociation,
)
from galaxy.model.orm.scripts import get_config


class AssociationNullFix(ABC):

def __init__(self, association_model: Base):
self.assoc_model = association_model
self.assoc_name = association_model.__tablename__
self.where_clause = self.build_where_clause()

def run(self):
config = get_config(sys.argv, use_argparse=False, cwd=os.getcwd())
engine = create_engine(config["db_url"])

invalid_assocs = self.count_associations_with_nulls(engine)
if not invalid_assocs:
print(f"Your database does not contain invalid {self.assoc_name} records")
return

print(f"Your database contains {invalid_assocs} invalid {self.assoc_name} records")
answer = input(f'Delete {invalid_assocs} invalid records? (type "yes" to confirm)\n')
if answer.lower() == "yes":
self.delete_associations_with_nulls(engine)
else:
print("Operation aborted")

def count_associations_with_nulls(self, engine):
"""
Retrieve association records where one or both associated item ids are null.
"""
select_stmt = select(func.count()).where(self.where_clause)
with engine.connect() as conn:
return conn.scalar(select_stmt)

def delete_associations_with_nulls(self, engine):
"""
Delete association records where one or both associated item ids are null.
"""
delete_stmt = delete(self.assoc_model).where(self.where_clause)
with engine.begin() as conn:
result = conn.execute(delete_stmt)
conn.commit()
print(f"{result.rowcount} invalid records have been deleted")

@abstractmethod
def build_where_clause(self):
"""Build where clause for filtering records containing nulls instead of associated item ids"""


class UserGroupAssociationNullFix(AssociationNullFix):

def build_where_clause(self):
return or_(UserGroupAssociation.user_id == null(), UserGroupAssociation.group_id == null())


class UserRoleAssociationNullFix(AssociationNullFix):

def build_where_clause(self):
return or_(UserRoleAssociation.user_id == null(), UserRoleAssociation.role_id == null())


class GroupRoleAssociationNullFix(AssociationNullFix):

def build_where_clause(self):
return or_(GroupRoleAssociation.group_id == null(), GroupRoleAssociation.role_id == null())
12 changes: 11 additions & 1 deletion scripts/db/fix_group_role_association_nulls.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# TODO
import os
import sys

sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "lib")))

from galaxy.model import GroupRoleAssociation
from galaxy.model.scripts.association_table_fixer import GroupRoleAssociationNullFix

if __name__ == "__main__":
assoc_fix = GroupRoleAssociationNullFix(GroupRoleAssociation)
assoc_fix.run()
12 changes: 11 additions & 1 deletion scripts/db/fix_user_group_association_nulls.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# TODO
import os
import sys

sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "lib")))

from galaxy.model import UserGroupAssociation
from galaxy.model.scripts.association_table_fixer import UserGroupAssociationNullFix

if __name__ == "__main__":
assoc_fix = UserGroupAssociationNullFix(UserGroupAssociation)
assoc_fix.run()
12 changes: 11 additions & 1 deletion scripts/db/fix_user_role_association_nulls.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
# TODO
import os
import sys

sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "lib")))

from galaxy.model import UserRoleAssociation
from galaxy.model.scripts.association_table_fixer import UserRoleAssociationNullFix

if __name__ == "__main__":
assoc_fix = UserRoleAssociationNullFix(UserRoleAssociation)
assoc_fix.run()

0 comments on commit c1a9264

Please sign in to comment.