148 lines
5.9 KiB
Markdown
148 lines
5.9 KiB
Markdown
# Product Profile Ingestion
|
|
|
|
Data ingestion pipeline for an agricultural treatment assistant. It reads local product profile JSON files and label-chunk JSONL files, then loads them into the configured backends:
|
|
|
|
- **Weaviate** — stores the semantic `retrieval_summary` from product profiles in the `ProductProfile` collection for vector search.
|
|
- **Microsoft SQL Server** — stores structured product metadata in `products`, per-crop use rules in `product_uses`, and label text chunks in `label_chunks`.
|
|
|
|
The pipeline is **idempotent**: a hash manifest (`.processed_manifest.json`) tracks which files have already been ingested, so re-running skips unchanged files unless `--force` is used.
|
|
|
|
## Prerequisites
|
|
|
|
- Python 3.10+
|
|
- [Docker](https://www.docker.com/) (for local Weaviate)
|
|
- Microsoft SQL Server with the `products`, `product_uses`, and `label_chunks` tables already created
|
|
- [ODBC Driver for SQL Server](https://learn.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server) (e.g. ODBC Driver 17 or 18)
|
|
|
|
## Setup
|
|
|
|
1. **Clone the repository** and enter the project directory.
|
|
|
|
2. **Create a virtual environment** and install dependencies:
|
|
|
|
```bash
|
|
python -m venv venv
|
|
# Windows
|
|
venv\Scripts\activate
|
|
# macOS / Linux
|
|
source venv/bin/activate
|
|
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
3. **Configure environment variables**:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
Edit `.env` with your Gemini API key, Weaviate connection settings, and SQL Server credentials.
|
|
|
|
4. **Start Weaviate** (uses the Gemini `text2vec-google` vectorizer; requires v1.32+ for `taskType` support):
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
5. **Create the Weaviate collection** (or let `ingest.py` create it on first run):
|
|
|
|
```bash
|
|
python setup_weaviate.py
|
|
```
|
|
|
|
The `ProductProfile` collection is configured to embed `retrieval_summary` with `gemini-embedding-001` and the `RETRIEVAL_DOCUMENT` task type. If you change embedding settings on an existing database, recreate the collection:
|
|
|
|
```bash
|
|
python setup_weaviate.py --recreate
|
|
python ingest.py --force
|
|
```
|
|
|
|
## Usage
|
|
|
|
Place product profile JSON files under `data/productProfiles/` and label-chunk JSONL files under `data/chunks/`, then run:
|
|
|
|
```bash
|
|
# Process new or changed profile and chunk files
|
|
python ingest.py
|
|
|
|
# Scan different directories
|
|
python ingest.py --profiles-dir path/to/profiles
|
|
python ingest.py --chunks-dir path/to/chunks
|
|
|
|
# Process a single file
|
|
python ingest.py --file data/productProfiles/ramin_sc_0916.json
|
|
python ingest.py --chunk-file data/chunks/delan_pro_16562.jsonl
|
|
|
|
# Reprocess everything, ignoring the manifest
|
|
python ingest.py --force
|
|
```
|
|
|
|
Profiles are processed before chunks in each run. Chunk rows reference `product_id` as a foreign key to `products`, so the matching product profile should be ingested first (the default run order handles this when both files are present).
|
|
|
|
Exit code `0` means all targeted files succeeded; `1` means at least one file failed (partial SQL transactions are rolled back per file).
|
|
|
|
## Configuration
|
|
|
|
| Variable | Required | Default | Description |
|
|
|----------|----------|---------|-------------|
|
|
| `GEMINI_API_KEY` | Yes | — | API key for Weaviate's Gemini vectorizer |
|
|
| `WEAVIATE_HOST` | No | `localhost` | Weaviate HTTP host |
|
|
| `WEAVIATE_HTTP_PORT` | No | `8080` | Weaviate HTTP port |
|
|
| `WEAVIATE_GRPC_PORT` | No | `50051` | Weaviate gRPC port |
|
|
| `SQL_DRIVER` | Yes | — | ODBC driver name (e.g. `ODBC Driver 17 for SQL Server`) |
|
|
| `SQL_SERVER` | Yes | — | SQL Server hostname |
|
|
| `SQL_DATABASE` | Yes | — | Database name |
|
|
| `SQL_USERNAME` | Yes | — | SQL login |
|
|
| `SQL_PASSWORD` | Yes | — | SQL password |
|
|
|
|
## Product profile JSON format
|
|
|
|
Each file must include at least `product_id`, `product_name`, and `retrieval_summary`. See `data/productProfiles/ramin_sc_0916.json` for a full example with metadata arrays and `uses` rules.
|
|
|
|
**Weaviate** receives:
|
|
|
|
- `product_id`, `product_name`, `retrieval_summary`
|
|
|
|
**SQL `products`** receives global metadata (registration, manufacturer, action flags, spray volumes, JSON-encoded arrays for ingredients, crops, diseases, etc.).
|
|
|
|
**SQL `product_uses`** receives one row per entry in the `uses` array (crop, disease, dose ranges, treatment intervals, growth stages, and related fields).
|
|
|
|
## Label chunk JSONL format
|
|
|
|
Each `.jsonl` file contains one JSON object per line. See `data/chunks/delan_pro_16562.jsonl` for an example.
|
|
|
|
**SQL `label_chunks`** receives one row per line with:
|
|
|
|
| JSON field | SQL column | Notes |
|
|
|------------|------------|-------|
|
|
| `chunk_id` | `chunk_id` | Primary key |
|
|
| `product_id` | `product_id` | Foreign key to `products` |
|
|
| `product_name` | `product_name` | |
|
|
| `target_crops` | `target_crops` | Stored as JSON string via `json.dumps()` |
|
|
| `target_diseases` | `target_diseases` | Stored as JSON string via `json.dumps()` |
|
|
| `chunk_type` | `chunk_type` | |
|
|
| `chunk_text` | `chunk_text` | |
|
|
|
|
On re-ingestion, all existing `label_chunks` rows for the file's `product_id` are deleted and replaced with the fresh set from the file.
|
|
|
|
## Project layout
|
|
|
|
```
|
|
product_profile_ingestion/
|
|
├── data/
|
|
│ ├── productProfiles/ # Product profile JSON files (*.json)
|
|
│ └── chunks/ # Label-chunk JSONL files (*.jsonl)
|
|
├── ingest.py # Main ingestion script
|
|
├── setup_weaviate.py # ProductProfile collection schema (Gemini embeddings)
|
|
├── requirements.txt # Python dependencies
|
|
├── docker-compose.yml # Local Weaviate instance
|
|
├── .env.example # Environment variable template
|
|
└── .processed_manifest.json # Generated at runtime (gitignored)
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
- [weaviate-client](https://weaviate.io/developers/weaviate/client-libraries/python) — Weaviate Python client
|
|
- [pyodbc](https://github.com/mkleehammer/pyodbc) — SQL Server connectivity
|
|
- [python-dotenv](https://github.com/theskumar/python-dotenv) — Load `.env` configuration
|