mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-10 04:00:35 +00:00
270 lines
7.0 KiB
Markdown
270 lines
7.0 KiB
Markdown
# Apache Arrow Exporter
|
|
|
|
## Overview
|
|
|
|
The Apache Arrow exporter provides high-performance columnar data export for Semantica's knowledge graphs, entities, and relationships. It uses explicit schemas (no inference) and writes Arrow IPC files (.arrow) that are compatible with Pandas and DuckDB.
|
|
|
|
## Features
|
|
|
|
- **Explicit Schemas**: Pre-defined schemas for entities and relationships (no inference)
|
|
- **Columnar Format**: Efficient storage and fast analytics
|
|
- **Metadata Support**: Converts metadata dictionaries to Arrow struct fields
|
|
- **Field Normalization**: Handles various entity and relationship field name variations
|
|
- **Progress Tracking**: Integrated progress monitoring
|
|
- **Error Handling**: Structured error handling with detailed logging
|
|
- **Pandas/DuckDB Compatible**: Direct conversion to DataFrames and SQL queries
|
|
|
|
## Installation
|
|
|
|
The Arrow exporter requires PyArrow:
|
|
|
|
```bash
|
|
pip install pyarrow
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Basic Usage
|
|
|
|
```python
|
|
from semantica.export import ArrowExporter
|
|
|
|
# Initialize exporter
|
|
exporter = ArrowExporter()
|
|
|
|
# Export entities
|
|
entities = [
|
|
{"id": "e1", "text": "Alice", "type": "Person", "confidence": 0.95},
|
|
{"id": "e2", "text": "Acme Corp", "type": "Organization", "confidence": 0.88}
|
|
]
|
|
exporter.export_entities(entities, "entities.arrow")
|
|
|
|
# Export relationships
|
|
relationships = [
|
|
{"id": "r1", "source_id": "e1", "target_id": "e2", "type": "WORKS_FOR"}
|
|
]
|
|
exporter.export_relationships(relationships, "relationships.arrow")
|
|
|
|
# Export knowledge graph
|
|
knowledge_graph = {
|
|
"entities": entities,
|
|
"relationships": relationships
|
|
}
|
|
exporter.export_knowledge_graph(knowledge_graph, "kg_base")
|
|
# Creates: kg_base_entities.arrow, kg_base_relationships.arrow
|
|
```
|
|
|
|
### Using Convenience Function
|
|
|
|
```python
|
|
from semantica.export import export_arrow
|
|
|
|
# Simple export
|
|
export_arrow(entities, "entities.arrow")
|
|
|
|
# Export multiple types
|
|
data = {
|
|
"entities": entities,
|
|
"relationships": relationships
|
|
}
|
|
export_arrow(data, "output_base")
|
|
```
|
|
|
|
### With Compression
|
|
|
|
```python
|
|
# Use LZ4 compression
|
|
exporter = ArrowExporter(compression="lz4")
|
|
exporter.export_entities(entities, "entities_compressed.arrow")
|
|
```
|
|
|
|
## Schemas
|
|
|
|
### Entity Schema
|
|
|
|
```python
|
|
ENTITY_SCHEMA = pa.schema([
|
|
pa.field("id", pa.string(), nullable=False),
|
|
pa.field("text", pa.string(), nullable=True),
|
|
pa.field("type", pa.string(), nullable=True),
|
|
pa.field("confidence", pa.float64(), nullable=True),
|
|
pa.field("start", pa.int64(), nullable=True),
|
|
pa.field("end", pa.int64(), nullable=True),
|
|
pa.field("metadata", pa.struct([
|
|
pa.field("keys", pa.list_(pa.string())),
|
|
pa.field("values", pa.list_(pa.string()))
|
|
]), nullable=True),
|
|
])
|
|
```
|
|
|
|
### Relationship Schema
|
|
|
|
```python
|
|
RELATIONSHIP_SCHEMA = pa.schema([
|
|
pa.field("id", pa.string(), nullable=False),
|
|
pa.field("source_id", pa.string(), nullable=False),
|
|
pa.field("target_id", pa.string(), nullable=False),
|
|
pa.field("type", pa.string(), nullable=True),
|
|
pa.field("confidence", pa.float64(), nullable=True),
|
|
pa.field("metadata", pa.struct([
|
|
pa.field("keys", pa.list_(pa.string())),
|
|
pa.field("values", pa.list_(pa.string()))
|
|
]), nullable=True),
|
|
])
|
|
```
|
|
|
|
## Field Normalization
|
|
|
|
The exporter automatically normalizes field names:
|
|
|
|
**Entities:**
|
|
- `text`, `label`, `name` → `text`
|
|
- `type`, `entity_type` → `type`
|
|
- `id`, `entity_id` → `id`
|
|
- `start`, `start_offset` → `start`
|
|
- `end`, `end_offset` → `end`
|
|
|
|
**Relationships:**
|
|
- `source`, `source_id` → `source_id`
|
|
- `target`, `target_id` → `target_id`
|
|
- `type`, `relationship_type` → `type`
|
|
|
|
## Reading Arrow Files
|
|
|
|
### With PyArrow
|
|
|
|
```python
|
|
import pyarrow as pa
|
|
import pyarrow.ipc as ipc
|
|
|
|
with pa.OSFile("entities.arrow", 'rb') as source:
|
|
with ipc.open_file(source) as reader:
|
|
table = reader.read_all()
|
|
print(table.schema)
|
|
print(table.to_pandas())
|
|
```
|
|
|
|
### With Pandas
|
|
|
|
```python
|
|
import pandas as pd
|
|
import pyarrow.ipc as ipc
|
|
|
|
with ipc.open_file("entities.arrow") as reader:
|
|
df = reader.read_all().to_pandas()
|
|
print(df)
|
|
```
|
|
|
|
### With DuckDB
|
|
|
|
```python
|
|
import duckdb
|
|
|
|
# Query Arrow file directly
|
|
result = duckdb.query("SELECT * FROM 'entities.arrow' WHERE type = 'Person'")
|
|
print(result.df())
|
|
```
|
|
|
|
## Methods
|
|
|
|
### `export(data, file_path, schema=None, **options)`
|
|
|
|
Generic export method that handles both single and multiple files.
|
|
|
|
**Parameters:**
|
|
- `data`: List of dicts or dict with list values
|
|
- `file_path`: Output file path (base path for dict exports)
|
|
- `schema`: Optional Arrow schema (auto-detected if not provided)
|
|
- `**options`: Additional options
|
|
|
|
### `export_entities(entities, file_path, **options)`
|
|
|
|
Export entities to Arrow IPC file with normalization.
|
|
|
|
**Parameters:**
|
|
- `entities`: List of entity dictionaries
|
|
- `file_path`: Output Arrow file path
|
|
- `**options`: Additional options
|
|
|
|
### `export_relationships(relationships, file_path, **options)`
|
|
|
|
Export relationships to Arrow IPC file with normalization.
|
|
|
|
**Parameters:**
|
|
- `relationships`: List of relationship dictionaries
|
|
- `file_path`: Output Arrow file path
|
|
- `**options`: Additional options
|
|
|
|
### `export_knowledge_graph(knowledge_graph, base_path, **options)`
|
|
|
|
Export knowledge graph to multiple Arrow files.
|
|
|
|
**Parameters:**
|
|
- `knowledge_graph`: Knowledge graph dictionary with 'entities' and 'relationships'
|
|
- `base_path`: Base path for output files (without extension)
|
|
- `**options`: Additional options
|
|
|
|
## Examples
|
|
|
|
See `examples/arrow_export_example.py` for comprehensive usage examples.
|
|
|
|
## Testing
|
|
|
|
Run the test suite:
|
|
|
|
```bash
|
|
# All Arrow exporter tests
|
|
pytest tests/test_arrow_exporter.py -v
|
|
|
|
# Integration tests
|
|
pytest tests/test_export_module.py::TestExportModule::test_arrow_exporter -v
|
|
```
|
|
|
|
## Performance Benefits
|
|
|
|
- **Columnar Storage**: Faster analytics on specific columns
|
|
- **Compression**: Smaller file sizes (especially with LZ4/ZSTD)
|
|
- **Zero-Copy**: Memory-efficient data transfer
|
|
- **Cross-Language**: Works with Python, R, Julia, JavaScript, and more
|
|
- **SQL Queries**: Direct querying with DuckDB without loading into memory
|
|
|
|
## Comparison with Other Formats
|
|
|
|
| Feature | Arrow | CSV | JSON |
|
|
|---------|-------|-----|------|
|
|
| Type Safety | ✓ | ✗ | ✗ |
|
|
| Compression | ✓ | ✗ | ✗ |
|
|
| Schema Validation | ✓ | ✗ | ✗ |
|
|
| Pandas Compatible | ✓ | ✓ | ✓ |
|
|
| DuckDB Native | ✓ | ✓ | ✗ |
|
|
| Binary Format | ✓ | ✗ | ✗ |
|
|
| Human Readable | ✗ | ✓ | ✓ |
|
|
|
|
## Architecture
|
|
|
|
The Arrow exporter follows Semantica's export architecture:
|
|
|
|
1. **Normalization**: Field names are normalized to consistent format
|
|
2. **Schema Application**: Explicit schemas ensure type safety
|
|
3. **Metadata Conversion**: Dicts converted to Arrow struct fields
|
|
4. **Progress Tracking**: Integrated with Semantica's progress tracker
|
|
5. **Error Handling**: Structured exceptions with detailed messages
|
|
|
|
## Contributing
|
|
|
|
When contributing to the Arrow exporter:
|
|
|
|
1. Maintain explicit schemas (no inference)
|
|
2. Follow existing code style and patterns
|
|
3. Add comprehensive tests for new features
|
|
4. Update this documentation
|
|
5. Ensure Pandas/DuckDB compatibility
|
|
|
|
## License
|
|
|
|
MIT License - See LICENSE file for details.
|
|
|
|
## Author
|
|
|
|
Semantica Contributors
|