diff --git a/src/core/migrations/versions/9de844252cd5_osint_source_group_cascade_delete.py b/src/core/migrations/versions/9de844252cd5_osint_source_group_cascade_delete.py new file mode 100644 index 00000000..098d613b --- /dev/null +++ b/src/core/migrations/versions/9de844252cd5_osint_source_group_cascade_delete.py @@ -0,0 +1,45 @@ +"""add cascade delete/null to osint_source_group releated tables + +Revision ID: 9de844252cd5 +Revises: 90249a322ae1 +Create Date: 2024-10-18 14:13:00.653593 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '9de844252cd5' +down_revision = '90249a322ae1' +branch_labels = None +depends_on = None + + +def upgrade(): + delete_previous() + + # news_item_aggregate + op.create_foreign_key('news_item_aggregate_osint_source_group_id_fkey', 'news_item_aggregate', 'osint_source_group', ['osint_source_group_id'], ['id'], ondelete='SET NULL') + # remote_node + op.create_foreign_key('remote_node_osint_source_group_id_fkey', 'remote_node', 'osint_source_group', ['osint_source_group_id'], ['id'], ondelete='SET NULL') + # news_item + op.create_foreign_key('osint_source_group_osint_source_osint_source_group_id_fkey', 'osint_source_group_osint_source', 'osint_source_group', ['osint_source_group_id'], ['id'], ondelete='CASCADE') + +def downgrade(): + delete_previous() + # news_item_aggregate + op.create_foreign_key('news_item_aggregate_osint_source_group_id_fkey', 'news_item_aggregate', 'osint_source_group', ['osint_source_group_id'], ['id']) + # remote_node + op.create_foreign_key('remote_node_osint_source_group_id_fkey', 'remote_node', 'osint_source_group', ['osint_source_group_id'], ['id']) + # news_item + op.create_foreign_key('osint_source_group_osint_source_osint_source_group_id_fkey', 'osint_source_group_osint_source', 'osint_source_group', ['osint_source_group_id'], ['id']) + +def delete_previous(): + print("deleting previous objects...", flush=True) + # news_item_aggregate + op.drop_constraint('news_item_aggregate_osint_source_group_id_fkey', 'news_item_aggregate', type_='foreignkey') + # remote_node + op.drop_constraint('remote_node_osint_source_group_id_fkey', 'remote_node', type_='foreignkey') + # news_item + op.drop_constraint('osint_source_group_osint_source_osint_source_group_id_fkey', 'osint_source_group_osint_source', type_='foreignkey') diff --git a/src/core/model/news_item.py b/src/core/model/news_item.py index 3535ec7c..c56d7f0f 100644 --- a/src/core/model/news_item.py +++ b/src/core/model/news_item.py @@ -941,13 +941,14 @@ def update_status(cls, aggregate_id): @classmethod def get_news_items_aggregate(cls, source_group, limit): limit = datetime.strptime(limit['limit'], '%d.%m.%Y - %H:%M') - - # TODO: Change condition in query to > - news_item_aggregates = cls.query.filter(cls.osint_source_group_id == source_group).filter(cls.created > limit). \ - all() + news_item_aggregates = cls.query.filter(cls.osint_source_group_id == source_group).filter(cls.created > limit).all() news_item_aggregate_schema = NewsItemAggregateSchema(many=True) return news_item_aggregate_schema.dumps(news_item_aggregates) + @classmethod + def get_news_items_aggregate_by_source_group(cls, source_group_id): + return cls.query.filter(cls.osint_source_group_id == source_group_id).all() + class NewsItemAggregateSearchIndex(db.Model): id = db.Column(db.Integer, primary_key=True) diff --git a/src/core/model/osint_source.py b/src/core/model/osint_source.py index bf0fe374..8d580e12 100644 --- a/src/core/model/osint_source.py +++ b/src/core/model/osint_source.py @@ -347,10 +347,19 @@ def add(cls, data): @classmethod def delete(cls, osint_source_group_id): + from model.news_item import NewsItemAggregate # must be here, because circular import error + osint_source_group = cls.query.get(osint_source_group_id) if osint_source_group.default is False: db.session.delete(osint_source_group) db.session.commit() + # Checking multiple source group assignments is problematic due to the existence of more NewsItemsAggregate records + # and the source assignment may change over time. Let's move them to the default group. + default_group = cls.get_default() + newsItemAggregates = NewsItemAggregate.get_news_items_aggregate_by_source_group(None) # we use db delete rule: set null + for item in newsItemAggregates: + item.osint_source_group_id = default_group.id + db.session.commit() return "", 200 else: return {'message': 'could_not_delete_default_group'}, 400