Spaces:
Sleeping
Sleeping
Commit
·
53b8615
1
Parent(s):
8992f8c
Import ~2000 common concepts
Browse files- concepts_to_import.json +0 -0
- manage_concepts.py +87 -0
- sfosr.db +2 -2
- sfosr_core/sfosr_database.py +86 -1
concepts_to_import.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
manage_concepts.py
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
"""
|
3 |
+
Script for managing SFOSR concepts (export/import).
|
4 |
+
"""
|
5 |
+
|
6 |
+
import argparse
|
7 |
+
import sys
|
8 |
+
import os
|
9 |
+
|
10 |
+
# Ensure the script can find the sfosr_core module
|
11 |
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
12 |
+
project_root = script_dir # Assumes script is in the root
|
13 |
+
sys.path.insert(0, project_root)
|
14 |
+
|
15 |
+
try:
|
16 |
+
from sfosr_core.sfosr_database import SFOSRDatabase
|
17 |
+
except ImportError as e:
|
18 |
+
print(f"Error: Could not import SFOSRDatabase. Make sure sfosr_core is accessible.")
|
19 |
+
print(f"PYTHONPATH: {sys.path}")
|
20 |
+
sys.exit(1)
|
21 |
+
|
22 |
+
DEFAULT_DB_PATH = "sfosr.db"
|
23 |
+
DEFAULT_JSON_PATH_EXPORT = "concepts_export.json" # Default for export
|
24 |
+
DEFAULT_JSON_PATH_IMPORT = "concepts_to_import.json" # Default for import
|
25 |
+
|
26 |
+
def main():
|
27 |
+
parser = argparse.ArgumentParser(description="Manage SFOSR concepts.")
|
28 |
+
subparsers = parser.add_subparsers(dest='action', help='Action to perform', required=True)
|
29 |
+
|
30 |
+
# Export command
|
31 |
+
parser_export = subparsers.add_parser('export', help='Export concepts to JSON')
|
32 |
+
parser_export.add_argument(
|
33 |
+
'--db-path',
|
34 |
+
default=DEFAULT_DB_PATH,
|
35 |
+
help=f"Path to the SFOSR database file (default: {DEFAULT_DB_PATH})"
|
36 |
+
)
|
37 |
+
parser_export.add_argument(
|
38 |
+
'--json-path',
|
39 |
+
default=DEFAULT_JSON_PATH_EXPORT,
|
40 |
+
help=f"Path to the output JSON file (default: {DEFAULT_JSON_PATH_EXPORT})"
|
41 |
+
)
|
42 |
+
|
43 |
+
# Import command
|
44 |
+
parser_import = subparsers.add_parser('import', help='Import concepts from JSON (adds only new concepts)')
|
45 |
+
parser_import.add_argument(
|
46 |
+
'--db-path',
|
47 |
+
default=DEFAULT_DB_PATH,
|
48 |
+
help=f"Path to the SFOSR database file (default: {DEFAULT_DB_PATH})"
|
49 |
+
)
|
50 |
+
parser_import.add_argument(
|
51 |
+
'--json-path',
|
52 |
+
default=DEFAULT_JSON_PATH_IMPORT,
|
53 |
+
help=f"Path to the input JSON file (default: {DEFAULT_JSON_PATH_IMPORT})"
|
54 |
+
)
|
55 |
+
|
56 |
+
args = parser.parse_args()
|
57 |
+
|
58 |
+
if not os.path.exists(args.db_path):
|
59 |
+
print(f"Error: Database file not found at {args.db_path}")
|
60 |
+
sys.exit(1)
|
61 |
+
|
62 |
+
db = SFOSRDatabase(db_path=args.db_path)
|
63 |
+
|
64 |
+
if args.action == 'export':
|
65 |
+
print(f"Exporting concepts from {args.db_path} to {args.json_path}...")
|
66 |
+
db.export_concepts_to_json(args.json_path)
|
67 |
+
|
68 |
+
elif args.action == 'import':
|
69 |
+
if not os.path.exists(args.json_path):
|
70 |
+
print(f"Error: Import JSON file not found at {args.json_path}")
|
71 |
+
sys.exit(1)
|
72 |
+
|
73 |
+
print(f"Importing concepts from {args.json_path} to {args.db_path}...")
|
74 |
+
try:
|
75 |
+
added, skipped = db.import_concepts_from_json(args.json_path)
|
76 |
+
# Optional: Add more feedback based on counts
|
77 |
+
except AttributeError:
|
78 |
+
print(f"Error: import_concepts_from_json method not found in SFOSRDatabase class in {db.__class__.__module__}.")
|
79 |
+
sys.exit(1)
|
80 |
+
except Exception as e:
|
81 |
+
print(f"An unexpected error occurred during import: {e}")
|
82 |
+
import traceback
|
83 |
+
traceback.print_exc() # Print stack trace for unexpected errors
|
84 |
+
sys.exit(1)
|
85 |
+
|
86 |
+
if __name__ == "__main__":
|
87 |
+
main()
|
sfosr.db
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2dced7d5030004004ac3532c01117075552aa621e9caa6396e7f6b8ea45bf248
|
3 |
+
size 319488
|
sfosr_core/sfosr_database.py
CHANGED
@@ -449,4 +449,89 @@ class SFOSRDatabase:
|
|
449 |
}
|
450 |
vectors.append(vector)
|
451 |
|
452 |
-
return vectors
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
}
|
450 |
vectors.append(vector)
|
451 |
|
452 |
+
return vectors
|
453 |
+
|
454 |
+
def export_concepts_to_json(self, filepath: str) -> None:
|
455 |
+
"""
|
456 |
+
Экспортирует все концепты из БД в JSON файл.
|
457 |
+
|
458 |
+
Args:
|
459 |
+
filepath: Путь к файлу для сохранения JSON.
|
460 |
+
"""
|
461 |
+
concepts = self.get_all_concepts() # Reuse existing method
|
462 |
+
try:
|
463 |
+
with open(filepath, 'w', encoding='utf-8') as f:
|
464 |
+
json.dump(concepts, f, ensure_ascii=False, indent=2)
|
465 |
+
print(f"Concepts successfully exported to {filepath}")
|
466 |
+
except IOError as e:
|
467 |
+
print(f"Error writing to file {filepath}: {e}")
|
468 |
+
except Exception as e:
|
469 |
+
print(f"An unexpected error occurred during export: {e}")
|
470 |
+
|
471 |
+
def import_concepts_from_json(self, filepath: str) -> Tuple[int, int]:
|
472 |
+
"""
|
473 |
+
Импортирует концепты из JSON файла, добавляя только те, которых нет в БД.
|
474 |
+
|
475 |
+
Args:
|
476 |
+
filepath: Путь к JSON файлу со списком концептов.
|
477 |
+
Каждый концепт должен быть словарем с ключами
|
478 |
+
'name', 'description', 'domain', 'level'. 'id' игнорируется.
|
479 |
+
|
480 |
+
Returns:
|
481 |
+
Кортеж (added_count, skipped_count): Количество добавленных и пропущенных концептов.
|
482 |
+
"""
|
483 |
+
added_count = 0
|
484 |
+
skipped_count = 0
|
485 |
+
try:
|
486 |
+
with open(filepath, 'r', encoding='utf-8') as f:
|
487 |
+
concepts_to_import = json.load(f)
|
488 |
+
|
489 |
+
if not isinstance(concepts_to_import, list):
|
490 |
+
print(f"Error: JSON file {filepath} should contain a list of concepts.")
|
491 |
+
return 0, 0
|
492 |
+
|
493 |
+
existing_names = self.get_all_concept_names() # Получаем существующие имена
|
494 |
+
|
495 |
+
with self as conn: # Используем одно соединение для всех вставок
|
496 |
+
cursor = conn.cursor()
|
497 |
+
for concept in concepts_to_import:
|
498 |
+
name = concept.get('name')
|
499 |
+
description = concept.get('description')
|
500 |
+
domain = concept.get('domain')
|
501 |
+
level = concept.get('level')
|
502 |
+
|
503 |
+
if not all([name, description, domain, level]):
|
504 |
+
print(f"Warning: Skipping concept due to missing fields: {concept}")
|
505 |
+
skipped_count += 1
|
506 |
+
continue
|
507 |
+
|
508 |
+
if name in existing_names:
|
509 |
+
# print(f"Skipping existing concept: {name}") # Optional: uncomment for verbose logging
|
510 |
+
skipped_count += 1
|
511 |
+
else:
|
512 |
+
try:
|
513 |
+
cursor.execute("""
|
514 |
+
INSERT INTO concepts (name, description, domain, level)
|
515 |
+
VALUES (?, ?, ?, ?)
|
516 |
+
""", (name, description, domain, level))
|
517 |
+
added_count += 1
|
518 |
+
existing_names.add(name) # Добавляем в сет, чтобы не добавить дубль из самого файла
|
519 |
+
except sqlite3.Error as e:
|
520 |
+
print(f"Error inserting concept {name}: {e}")
|
521 |
+
skipped_count += 1
|
522 |
+
# Optionally rollback or handle error differently
|
523 |
+
|
524 |
+
conn.commit() # Коммитим все изменения разом
|
525 |
+
|
526 |
+
print(f"Import finished. Added: {added_count}, Skipped (existing or invalid): {skipped_count}")
|
527 |
+
return added_count, skipped_count
|
528 |
+
|
529 |
+
except FileNotFoundError:
|
530 |
+
print(f"Error: Import file not found at {filepath}")
|
531 |
+
return 0, 0
|
532 |
+
except json.JSONDecodeError as e:
|
533 |
+
print(f"Error decoding JSON from {filepath}: {e}")
|
534 |
+
return 0, 0
|
535 |
+
except Exception as e:
|
536 |
+
print(f"An unexpected error occurred during import: {e}")
|
537 |
+
return 0, 0
|