structured2graph 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. __init__.py +47 -0
  2. core/__init__.py +23 -0
  3. core/hygm/__init__.py +74 -0
  4. core/hygm/hygm.py +2351 -0
  5. core/hygm/models/__init__.py +82 -0
  6. core/hygm/models/graph_models.py +667 -0
  7. core/hygm/models/llm_models.py +229 -0
  8. core/hygm/models/operations.py +176 -0
  9. core/hygm/models/sources.py +68 -0
  10. core/hygm/models/user_operations.py +139 -0
  11. core/hygm/strategies/__init__.py +17 -0
  12. core/hygm/strategies/base.py +36 -0
  13. core/hygm/strategies/deterministic.py +262 -0
  14. core/hygm/strategies/llm.py +904 -0
  15. core/hygm/validation/__init__.py +38 -0
  16. core/hygm/validation/base.py +194 -0
  17. core/hygm/validation/graph_schema_validator.py +687 -0
  18. core/hygm/validation/memgraph_data_validator.py +991 -0
  19. core/migration_agent.py +1369 -0
  20. core/schema/spec.json +155 -0
  21. core/utils/meta_graph.py +108 -0
  22. database/__init__.py +36 -0
  23. database/adapters/__init__.py +11 -0
  24. database/adapters/memgraph.py +318 -0
  25. database/adapters/mysql.py +311 -0
  26. database/adapters/postgresql.py +335 -0
  27. database/analyzer.py +396 -0
  28. database/factory.py +219 -0
  29. database/models.py +209 -0
  30. main.py +518 -0
  31. query_generation/__init__.py +20 -0
  32. query_generation/cypher_generator.py +129 -0
  33. query_generation/schema_utilities.py +88 -0
  34. structured2graph-0.1.1.dist-info/METADATA +197 -0
  35. structured2graph-0.1.1.dist-info/RECORD +41 -0
  36. structured2graph-0.1.1.dist-info/WHEEL +4 -0
  37. structured2graph-0.1.1.dist-info/entry_points.txt +2 -0
  38. structured2graph-0.1.1.dist-info/licenses/LICENSE +21 -0
  39. utils/__init__.py +57 -0
  40. utils/config.py +235 -0
  41. utils/environment.py +404 -0
database/models.py ADDED
@@ -0,0 +1,209 @@
1
+ """
2
+ Database data models.
3
+
4
+ This module contains all the data structures used to represent
5
+ database schema information in a standardized way.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from enum import Enum
10
+ from typing import Dict, List, Any, Optional
11
+
12
+
13
+ class TableType(Enum):
14
+ """Enumeration of table types."""
15
+
16
+ ENTITY = "entity"
17
+ JOIN = "join"
18
+ VIEW = "view"
19
+ LOOKUP = "lookup"
20
+
21
+
22
+ @dataclass
23
+ class ColumnInfo:
24
+ """Standardized column information across different database systems."""
25
+
26
+ name: str
27
+ data_type: str
28
+ is_nullable: bool
29
+ is_primary_key: bool
30
+ is_foreign_key: bool
31
+ default_value: Optional[Any] = None
32
+ auto_increment: bool = False
33
+ max_length: Optional[int] = None
34
+ precision: Optional[int] = None
35
+ scale: Optional[int] = None
36
+
37
+ def to_hygm_format(self) -> Dict[str, Any]:
38
+ """Convert to HyGM-compatible format."""
39
+ # Determine key type
40
+ key_type = ""
41
+ if self.is_primary_key:
42
+ key_type = "PRI"
43
+ elif self.is_foreign_key:
44
+ key_type = "MUL" # MySQL convention for foreign keys
45
+
46
+ # Determine null constraint
47
+ null_constraint = "NO" if not self.is_nullable else "YES"
48
+
49
+ # Build type string with length/precision info
50
+ type_str = self.data_type
51
+ if self.max_length:
52
+ type_str += f"({self.max_length})"
53
+ elif self.precision and self.scale:
54
+ type_str += f"({self.precision},{self.scale})"
55
+ elif self.precision:
56
+ type_str += f"({self.precision})"
57
+
58
+ # Build extra field
59
+ extra = ""
60
+ if self.auto_increment:
61
+ extra = "auto_increment"
62
+
63
+ return {
64
+ "field": self.name,
65
+ "type": type_str,
66
+ "null": null_constraint,
67
+ "key": key_type,
68
+ "default": self.default_value,
69
+ "extra": extra,
70
+ }
71
+
72
+
73
+ @dataclass
74
+ class ForeignKeyInfo:
75
+ """Standardized foreign key information."""
76
+
77
+ column_name: str
78
+ referenced_table: str
79
+ referenced_column: str
80
+ constraint_name: Optional[str] = None
81
+
82
+ def to_hygm_format(self) -> Dict[str, Any]:
83
+ """Convert to HyGM-compatible format."""
84
+ hygm_fk = {
85
+ "column": self.column_name,
86
+ "referenced_table": self.referenced_table,
87
+ "referenced_column": self.referenced_column,
88
+ }
89
+ if self.constraint_name:
90
+ hygm_fk["constraint_name"] = self.constraint_name
91
+ return hygm_fk
92
+
93
+
94
+ @dataclass
95
+ class TableInfo:
96
+ """Standardized table information."""
97
+
98
+ name: str
99
+ table_type: TableType
100
+ columns: List[ColumnInfo]
101
+ foreign_keys: List[ForeignKeyInfo]
102
+ row_count: int
103
+ primary_keys: List[str]
104
+ indexes: List[Dict[str, Any]]
105
+
106
+ def to_hygm_format(self) -> Dict[str, Any]:
107
+ """Convert to HyGM-compatible format."""
108
+ # Format columns for HyGM
109
+ schema = [col.to_hygm_format() for col in self.columns]
110
+
111
+ # Format foreign keys for HyGM
112
+ foreign_keys = [fk.to_hygm_format() for fk in self.foreign_keys]
113
+
114
+ return {
115
+ "schema": schema,
116
+ "foreign_keys": foreign_keys,
117
+ "type": self.table_type.value,
118
+ "row_count": self.row_count,
119
+ "primary_keys": self.primary_keys,
120
+ "indexes": self.indexes,
121
+ }
122
+
123
+
124
+ @dataclass
125
+ class RelationshipInfo:
126
+ """Standardized relationship information."""
127
+
128
+ relationship_type: str # "one_to_many", "many_to_many", "one_to_one"
129
+ from_table: str
130
+ from_column: str
131
+ to_table: str
132
+ to_column: str
133
+ join_table: Optional[str] = None
134
+ join_from_column: Optional[str] = None
135
+ join_to_column: Optional[str] = None
136
+ additional_properties: Optional[List[str]] = None
137
+
138
+ def to_hygm_format(self) -> Dict[str, Any]:
139
+ """Convert to HyGM-compatible format."""
140
+ hygm_rel = {
141
+ "type": self.relationship_type,
142
+ "from_table": self.from_table,
143
+ "from_column": self.from_column,
144
+ "to_table": self.to_table,
145
+ "to_column": self.to_column,
146
+ }
147
+
148
+ # Add many-to-many specific fields
149
+ if self.relationship_type == "many_to_many":
150
+ hygm_rel["join_table"] = self.join_table
151
+ hygm_rel["join_from_column"] = self.join_from_column
152
+ hygm_rel["join_to_column"] = self.join_to_column
153
+ hygm_rel["additional_properties"] = self.additional_properties or []
154
+
155
+ return hygm_rel
156
+
157
+
158
+ @dataclass
159
+ class DatabaseStructure:
160
+ """Standardized database structure representation."""
161
+
162
+ tables: Dict[str, TableInfo]
163
+ entity_tables: Dict[str, TableInfo]
164
+ join_tables: Dict[str, TableInfo]
165
+ view_tables: Dict[str, TableInfo]
166
+ relationships: List[RelationshipInfo]
167
+ sample_data: Dict[str, List[Dict[str, Any]]]
168
+ table_counts: Dict[str, int]
169
+ database_name: str
170
+ database_type: str
171
+
172
+ def to_hygm_format(self) -> Dict[str, Any]:
173
+ """
174
+ Convert to HyGM-compatible format.
175
+
176
+ This replaces the need for DatabaseDataInterface.get_hygm_data_structure()
177
+ """
178
+ # Convert tables to HyGM format
179
+ hygm_tables = {}
180
+ hygm_entity_tables = {}
181
+ hygm_join_tables = {}
182
+ hygm_views = {}
183
+
184
+ for table_name, table_info in self.tables.items():
185
+ hygm_table = table_info.to_hygm_format()
186
+ hygm_tables[table_name] = hygm_table
187
+
188
+ # Categorize based on existing categorization
189
+ if table_name in self.view_tables:
190
+ hygm_views[table_name] = hygm_table
191
+ elif table_name in self.join_tables:
192
+ hygm_join_tables[table_name] = hygm_table
193
+ else:
194
+ hygm_entity_tables[table_name] = hygm_table
195
+
196
+ # Convert relationships to HyGM format
197
+ hygm_relationships = [rel.to_hygm_format() for rel in self.relationships]
198
+
199
+ return {
200
+ "tables": hygm_tables,
201
+ "entity_tables": hygm_entity_tables,
202
+ "join_tables": hygm_join_tables,
203
+ "views": hygm_views,
204
+ "relationships": hygm_relationships,
205
+ "sample_data": self.sample_data,
206
+ "table_counts": self.table_counts,
207
+ "database_type": self.database_type,
208
+ "database_name": self.database_name,
209
+ }