Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| Script để xóa tất cả dữ liệu không liên quan đến 4 file legal documents được chỉ định. | |
| Chỉ giữ lại: | |
| 1. 1. BIÊN SOẠN THÔNG TƯ 02.docx | |
| 2. 264-QD_TW_644732 sửa đổi bổ sung QĐ 69 về kỷ luật đảng viên.doc | |
| 3. QD-69-TW về kỷ luật đảng viên.pdf | |
| 4. THÔNG TƯ 02 VỀ XỬ LÝ ĐIỀU LỆNH TRONG CAND.docx | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| from pathlib import Path | |
| ROOT_DIR = Path(__file__).resolve().parents[2] | |
| BACKEND_DIR = ROOT_DIR / "backend" | |
| # Add backend directory to sys.path for Django | |
| if str(BACKEND_DIR) not in sys.path: | |
| sys.path.insert(0, str(BACKEND_DIR)) | |
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hue_portal.hue_portal.settings") | |
| import django | |
| django.setup() | |
| from django.db import transaction | |
| from hue_portal.core.models import ( | |
| Fine, | |
| Office, | |
| Procedure, | |
| Advisory, | |
| LegalDocument, | |
| LegalSection, | |
| LegalDocumentImage, | |
| ) | |
| # Danh sách các file được giữ lại (theo code hoặc original_filename) | |
| KEEP_DOCUMENT_CODES = [ | |
| "QD-69-TW", | |
| "TT-02-CAND", | |
| "TT-02-BIEN-SOAN", | |
| "264-QD-TW", | |
| ] | |
| KEEP_FILENAMES = [ | |
| "QD-69-TW về kỷ luật đảng viên.pdf", | |
| "THÔNG TƯ 02 VỀ XỬ LÝ ĐIỀU LỆNH TRONG CAND.docx", | |
| "1. BIÊN SOẠN THÔNG TƯ 02.docx", | |
| "264-QD_TW_644732 sửa đổi bổ sung QĐ 69 về kỷ luật đảng viên.doc", | |
| ] | |
| def get_keep_document_ids() -> set[int]: | |
| """Lấy IDs của các LegalDocument cần giữ lại.""" | |
| keep_ids = set() | |
| # Tìm theo code | |
| for code in KEEP_DOCUMENT_CODES: | |
| docs = LegalDocument.objects.filter(code=code) | |
| for doc in docs: | |
| keep_ids.add(doc.id) | |
| print(f"✅ Giữ lại document: {doc.code} - {doc.title}") | |
| # Tìm theo original_filename | |
| for filename in KEEP_FILENAMES: | |
| docs = LegalDocument.objects.filter(original_filename__icontains=filename.split("/")[-1]) | |
| for doc in docs: | |
| keep_ids.add(doc.id) | |
| if doc.id not in keep_ids: | |
| print(f"✅ Giữ lại document: {doc.code} - {doc.title} (theo filename)") | |
| return keep_ids | |
| def cleanup_unrelated_data(dry_run: bool = False) -> None: | |
| """Xóa tất cả dữ liệu không liên quan đến 4 file được chỉ định.""" | |
| print("=" * 60) | |
| print("🧹 Dọn dẹp dữ liệu không liên quan") | |
| print("=" * 60) | |
| if dry_run: | |
| print("⚠️ DRY RUN MODE - Không thực sự xóa dữ liệu") | |
| print() | |
| # Lấy IDs của documents cần giữ lại | |
| keep_doc_ids = get_keep_document_ids() | |
| print(f"\n📋 Sẽ giữ lại {len(keep_doc_ids)} document(s)") | |
| if not keep_doc_ids: | |
| print("⚠️ Không tìm thấy document nào cần giữ lại!") | |
| print(" Có thể các file chưa được load vào database.") | |
| print(" Chạy: python backend/scripts/load_legal_documents.py") | |
| return | |
| with transaction.atomic(): | |
| # 1. Xóa tất cả Fines | |
| fines_count = Fine.objects.count() | |
| if not dry_run: | |
| Fine.objects.all().delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {fines_count} Fine(s)") | |
| # 2. Xóa tất cả Procedures | |
| procedures_count = Procedure.objects.count() | |
| if not dry_run: | |
| Procedure.objects.all().delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {procedures_count} Procedure(s)") | |
| # 3. Xóa tất cả Advisories | |
| advisories_count = Advisory.objects.count() | |
| if not dry_run: | |
| Advisory.objects.all().delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {advisories_count} Advisory(ies)") | |
| # 4. Xóa tất cả Offices | |
| offices_count = Office.objects.count() | |
| if not dry_run: | |
| Office.objects.all().delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {offices_count} Office(s)") | |
| # 5. Xóa LegalDocumentImage của documents không được giữ lại | |
| images_to_delete = LegalDocumentImage.objects.exclude(document_id__in=keep_doc_ids) | |
| images_count = images_to_delete.count() | |
| if not dry_run: | |
| images_to_delete.delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {images_count} LegalDocumentImage(s)") | |
| # 6. Xóa LegalSection của documents không được giữ lại | |
| sections_to_delete = LegalSection.objects.exclude(document_id__in=keep_doc_ids) | |
| sections_count = sections_to_delete.count() | |
| if not dry_run: | |
| sections_to_delete.delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {sections_count} LegalSection(s)") | |
| # 7. Xóa LegalDocument không được giữ lại | |
| docs_to_delete = LegalDocument.objects.exclude(id__in=keep_doc_ids) | |
| docs_count = docs_to_delete.count() | |
| if not dry_run: | |
| # Liệt kê các document sẽ bị xóa | |
| print(f"\n📄 Các document sẽ bị xóa ({docs_count}):") | |
| for doc in docs_to_delete: | |
| print(f" - {doc.code}: {doc.title}") | |
| docs_to_delete.delete() | |
| print(f"🗑️ {'Sẽ xóa' if dry_run else 'Đã xóa'} {docs_count} LegalDocument(s)") | |
| if dry_run: | |
| print("\n⚠️ DRY RUN - Không có dữ liệu nào bị xóa thực sự") | |
| print(" Chạy lại không có --dry-run để thực sự xóa") | |
| else: | |
| print("\n✅ Hoàn tất dọn dẹp!") | |
| print(f" Giữ lại {len(keep_doc_ids)} document(s)") | |
| print("\n📝 Bước tiếp theo:") | |
| print(" 1. Regenerate embeddings: python backend/scripts/generate_embeddings.py") | |
| print(" 2. Rebuild FAISS index: python backend/scripts/build_faiss_index.py") | |
| def main(): | |
| import argparse | |
| parser = argparse.ArgumentParser(description="Xóa dữ liệu không liên quan đến 4 file legal documents") | |
| parser.add_argument( | |
| "--dry-run", | |
| action="store_true", | |
| help="Chỉ hiển thị sẽ xóa gì, không thực sự xóa", | |
| ) | |
| args = parser.parse_args() | |
| cleanup_unrelated_data(dry_run=args.dry_run) | |
| if __name__ == "__main__": | |
| main() | |