Skip to content

Commit 69c5703

Browse files
committed
Merge Computations section into Operations
- Move computation chapter to 40-operations/050-populate.ipynb - Add new 060-orchestration.ipynb covering infrastructure concerns - Update cross-references in 20-concepts/04-integrity.md - Update cross-references in 30-design/015-table.ipynb - Remove 60-computation directory Operations section now contains: 1. Insert 2. Delete 3. Updates 4. Transactions 5. Populate (automated computation via make/populate) 6. Orchestration (infrastructure, containerization, monitoring)
1 parent 04e6200 commit 69c5703

5 files changed

Lines changed: 149 additions & 23 deletions

File tree

book/20-concepts/04-integrity.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Workflow integrity maintains valid operation sequences through:
162162

163163
**Covered in:**
164164
- [Foreign Keys](../30-design/030-foreign-keys.ipynb) — How foreign keys encode workflow dependencies
165-
- [Computation](../60-computation/010-computation.ipynb) — Automatic workflow execution and dependency resolution
165+
- [Populate](../40-operations/050-populate.ipynb) — Automatic workflow execution and dependency resolution
166166

167167
---
168168

book/30-design/015-table.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@
352352
{
353353
"cell_type": "markdown",
354354
"metadata": {},
355-
"source": "# Table Base Classes\n\nDataJoint provides four base classes for different data management patterns:\n\n| Base Class | Purpose | When to Use |\n|------------|---------|-------------|\n| `dj.Manual` | Manually entered data | Subject info, experimental protocols |\n| `dj.Lookup` | Reference data, rarely changes | Equipment lists, parameter sets |\n| `dj.Imported` | Data imported from external files | Raw recordings, behavioral videos |\n| `dj.Computed` | Derived from other tables | Spike sorting results, analyses |\n\nWe'll explore `Imported` and `Computed` tables in the [Computation](../60-computation/) section.\n\n```{seealso}\n- [Lookup Tables](018-lookup-tables.ipynb) — Managing reference data\n- [Computation](../60-computation/010-computation.ipynb) — Automated data processing\n```"
355+
"source": "# Table Base Classes\n\nDataJoint provides four base classes for different data management patterns:\n\n| Base Class | Purpose | When to Use |\n|------------|---------|-------------|\n| `dj.Manual` | Manually entered data | Subject info, experimental protocols |\n| `dj.Lookup` | Reference data, rarely changes | Equipment lists, parameter sets |\n| `dj.Imported` | Data imported from external files | Raw recordings, behavioral videos |\n| `dj.Computed` | Derived from other tables | Spike sorting results, analyses |\n\nWe'll explore `Imported` and `Computed` tables in the [Populate](050-populate.ipynb) chapter.\n\n```{seealso}\n- [Lookup Tables](018-lookup-tables.ipynb) — Managing reference data\n- [Populate](050-populate.ipynb) — Automated data processing\n```"
356356
},
357357
{
358358
"cell_type": "markdown",
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": "# Populate\n\nThe `populate` operation is the engine of workflow automation in DataJoint.\nWhile `insert`, `delete`, and `update` are manual operations, `populate` automates data entry for **Imported** and **Computed** tables based on dependencies defined in the schema.\n\nThis chapter connects the theoretical foundations of the [Relational Workflow Model](../20-concepts/05-workflows.md) to the practical `populate` operation.\n\n## The Relational Workflow Model in Action\n\nRecall that the **Relational Workflow Model** is built on four fundamental concepts:\n\n1. **Workflow Entity** — Each table represents an entity type created at a specific workflow step\n2. **Workflow Dependencies** — Foreign keys prescribe the order of operations\n3. **Workflow Steps** — Distinct phases where entity types are created (manual or automated)\n4. **Directed Acyclic Graph (DAG)** — The schema forms a graph structure ensuring valid execution sequences\n\nThe Relational Workflow Model defines a new class of databases: **Computational Databases**, where computational transformations are first-class citizens of the data model. In a computational database, the schema is not merely a passive data structure—it is an executable specification of the workflow itself.\n\n## From Declarative Schema to Executable Pipeline\n\nA DataJoint schema uses **table tiers** to distinguish different workflow roles:\n\n| Tier | Color | Role in Workflow |\n|------|-------|------------------|\n| **Lookup** | Gray | Static reference data and configuration parameters |\n| **Manual** | Green | Human-entered data or data from external systems |\n| **Imported** | Blue | Data acquired automatically from instruments or files |\n| **Computed** | Red | Derived data produced by computational transformations |\n\nBecause dependencies are explicit through foreign keys, DataJoint's `populate()` method can explore the DAG top-down: for every upstream key that has not been processed, it executes the table's `make()` method inside an atomic transaction. If anything fails, the transaction is rolled back, preserving **computational validity**—the guarantee that all derived data remains consistent with its upstream dependencies.\n\nThis is the essence of **workflow automation**: each table advertises what it depends on, and `populate()` runs only the computations that are still missing.\n\n## The `populate` Method\n\nThe `populate()` method is the engine of workflow automation. When called on a computed or imported table, it:\n\n1. **Identifies missing work** — Queries the key source (the join of all upstream dependencies) and subtracts keys already present in the table\n2. **Iterates over pending keys** — For each missing key, calls the table's `make()` method\n3. **Wraps each `make()` in a transaction** — Ensures atomicity: either all inserts succeed or none do\n4. **Handles errors gracefully** — Failed jobs are logged but do not stop the remaining work\n\n```python\n# Process all pending work\nDetection.populate(display_progress=True)\n\n# Process a specific subset\nDetection.populate(Image & \"image_id < 10\")\n\n# Distribute across workers\nDetection.populate(reserve_jobs=True)\n```\n\nThe `reserve_jobs=True` option enables parallel execution across multiple processes or machines by using the database itself for job coordination.\n\n## Transactional Integrity\n\nEach `make()` call executes inside an **ACID transaction**. This provides critical guarantees for computational workflows:\n\n- **Atomicity** — The entire computation either commits or rolls back as a unit\n- **Isolation** — Partial results are never visible to other processes\n- **Consistency** — The database moves from one valid state to another\n\nWhen a computed table has [part tables](../30-design/053-master-part.ipynb), the transaction boundary encompasses both the master and all its parts. The master's `make()` method is responsible for inserting everything within a single transactional scope. See the [Master-Part](../30-design/053-master-part.ipynb) chapter for detailed coverage of ACID semantics and the master's responsibility pattern.\n\n## Case Study: Blob Detection\n\nThe [Blob Detection](../80-examples/075-blob-detection.ipynb) example demonstrates these concepts in a compact image-analysis workflow:\n\n1. **Source data** — `Image` (manual) stores NumPy arrays as `longblob` fields\n2. **Parameter space** — `BlobParamSet` (lookup) defines detection configurations\n3. **Computation** — `Detection` (computed) depends on both upstream tables\n\nThe `Detection` table uses a master-part structure: the master row stores an aggregate (blob count), while `Detection.Blob` parts store per-feature coordinates. When `populate()` runs:\n\n- Each `(image_id, blob_paramset)` combination triggers one `make()` call\n- The `make()` method fetches inputs, runs detection, and inserts both master and parts\n- The transaction ensures all blob coordinates appear atomically with their count\n\n```python\nDetection.populate(display_progress=True)\n# Detection: 100%|██████████| 6/6 [00:01<00:00, 4.04it/s]\n```\n\nThis pattern—automation exploring combinatorics, then human curation—is common in scientific workflows. After reviewing results, the `SelectDetection` manual table records the preferred parameter set for each image. Because `SelectDetection` depends on `Detection`, it implicitly has access to all `Detection.Blob` parts for the selected detection.\n\n:::{seealso}\n- [Blob Detection](../80-examples/075-blob-detection.ipynb) — Complete working example\n- [Master-Part](../30-design/053-master-part.ipynb) — Transaction semantics and dependency implications\n:::\n\n## Why Computational Databases Matter\n\nThe Relational Workflow Model provides several key benefits:\n\n| Benefit | Description |\n|---------|-------------|\n| **Reproducibility** | Rerunning `populate()` regenerates derived tables from raw inputs |\n| **Dependency-aware scheduling** | DataJoint infers job order from foreign keys (the DAG structure) |\n| **Computational validity** | Transactions ensure downstream results stay consistent with upstream inputs |\n| **Provenance tracking** | The schema documents what was computed from what |\n\n## Practical Tips\n\n- **Develop incrementally** — Test `make()` logic with restrictions (e.g., `Table.populate(restriction)`) before processing all data\n- **Monitor progress** — Use `display_progress=True` for visibility during development\n- **Distribute work** — Use `reserve_jobs=True` when running multiple workers\n- **Use master-part for multi-row results** — When a computation produces both summary and detail rows, structure them as master and parts to keep them in the same transaction"
7+
},
8+
{
9+
"cell_type": "markdown",
10+
"metadata": {},
11+
"source": []
12+
}
13+
],
14+
"metadata": {
15+
"language_info": {
16+
"name": "python"
17+
}
18+
},
19+
"nbformat": 4,
20+
"nbformat_minor": 2
21+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "cell-0",
6+
"metadata": {},
7+
"source": [
8+
"# Orchestration\n",
9+
"\n",
10+
"While the `populate` operation provides the logic for automated computation, **orchestration** addresses the infrastructure and operational concerns of running these computations at scale:\n",
11+
"\n",
12+
"- **Infrastructure provisioning** — Allocating compute resources (servers, containers, cloud instances)\n",
13+
"- **Dependency management** — Ensuring consistent runtime environments across workers\n",
14+
"- **Automated execution** — Scheduling and triggering `populate` calls\n",
15+
"- **Observability** — Monitoring job progress, failures, and system health\n",
16+
"- **Performance and cost tracking** — Understanding resource utilization and expenses\n",
17+
"\n",
18+
"These concerns are **outside the scope of the core DataJoint library** (`datajoint-python`), which focuses on the data model and workflow logic. Orchestration is solved through complementary infrastructure.\n",
19+
"\n",
20+
"## The Orchestration Challenge\n",
21+
"\n",
22+
"A typical DataJoint workflow requires:\n",
23+
"\n",
24+
"1. **Database server** — MySQL/MariaDB instance with appropriate configuration\n",
25+
"2. **Worker processes** — Python environments with DataJoint and domain-specific packages\n",
26+
"3. **File storage** — For external blob storage (if using `dj.config['stores']`)\n",
27+
"4. **Job coordination** — Managing which workers process which jobs\n",
28+
"5. **Error handling** — Retrying failed jobs, alerting on persistent failures\n",
29+
"6. **Scaling** — Adding workers during high-demand periods\n",
30+
"\n",
31+
"The `populate(reserve_jobs=True)` option handles job coordination at the database level, but provisioning and managing the workers themselves requires additional infrastructure.\n",
32+
"\n",
33+
"## Commercial Solution: DataJoint Works\n",
34+
"\n",
35+
"[DataJoint Works](https://datajoint.com) is a managed platform that provides comprehensive orchestration:\n",
36+
"\n",
37+
"| Feature | Description |\n",
38+
"|---------|-------------|\n",
39+
"| **Managed databases** | Provisioned and configured MySQL instances |\n",
40+
"| **Container registry** | Store and version workflow container images |\n",
41+
"| **Compute clusters** | Auto-scaling worker pools (cloud or on-premise) |\n",
42+
"| **Job scheduler** | Automated triggering of `populate` operations |\n",
43+
"| **Monitoring dashboard** | Real-time visibility into job status and errors |\n",
44+
"| **Cost analytics** | Track compute and storage costs per workflow |\n",
45+
"\n",
46+
"This platform integrates directly with DataJoint schemas, providing a turnkey solution for teams that prefer managed infrastructure.\n",
47+
"\n",
48+
"## DIY Solutions\n",
49+
"\n",
50+
"Many teams build custom orchestration using standard DevOps tools. Common approaches include:\n",
51+
"\n",
52+
"### Containerization\n",
53+
"\n",
54+
"- **Docker** — Package DataJoint workflows with all dependencies\n",
55+
"- **Singularity/Apptainer** — Container runtime for HPC environments\n",
56+
"- **Conda environments** — Dependency management without full containerization\n",
57+
"\n",
58+
"### Container Orchestration\n",
59+
"\n",
60+
"- **Kubernetes** — Production-grade container orchestration\n",
61+
"- **Docker Swarm** — Simpler container clustering\n",
62+
"- **Nomad** — HashiCorp's workload orchestrator\n",
63+
"\n",
64+
"### Job Schedulers\n",
65+
"\n",
66+
"- **SLURM** — Common in academic HPC clusters\n",
67+
"- **PBS/Torque** — Traditional batch scheduling\n",
68+
"- **HTCondor** — High-throughput computing scheduler\n",
69+
"- **Apache Airflow** — DAG-based workflow orchestration\n",
70+
"- **Prefect** — Modern Python-native orchestration\n",
71+
"- **Celery** — Distributed task queue\n",
72+
"\n",
73+
"### Cloud Infrastructure\n",
74+
"\n",
75+
"- **AWS Batch** — Managed batch computing on AWS\n",
76+
"- **Google Cloud Run Jobs** — Serverless container execution\n",
77+
"- **Azure Container Instances** — On-demand container execution\n",
78+
"\n",
79+
"### Monitoring and Observability\n",
80+
"\n",
81+
"- **Prometheus + Grafana** — Metrics collection and visualization\n",
82+
"- **DataDog** — Commercial observability platform\n",
83+
"- **CloudWatch / Stackdriver** — Cloud-native monitoring\n",
84+
"\n",
85+
"### Database Hosting\n",
86+
"\n",
87+
"- **Amazon RDS** — Managed MySQL on AWS\n",
88+
"- **Google Cloud SQL** — Managed MySQL on GCP\n",
89+
"- **Self-hosted MySQL/MariaDB** — On-premise or VM-based\n",
90+
"\n",
91+
"## Choosing an Approach\n",
92+
"\n",
93+
"The right orchestration strategy depends on your team's context:\n",
94+
"\n",
95+
"| Factor | Managed Platform | DIY |\n",
96+
"|--------|-----------------|-----|\n",
97+
"| **Setup time** | Hours | Days to weeks |\n",
98+
"| **Maintenance** | Included | Team responsibility |\n",
99+
"| **Customization** | Platform constraints | Full flexibility |\n",
100+
"| **Cost model** | Subscription | Infrastructure costs |\n",
101+
"| **Existing infrastructure** | May duplicate | Leverages investments |\n",
102+
"| **Compliance requirements** | Check with vendor | Full control |\n",
103+
"\n",
104+
"Many teams start with DIY solutions using familiar tools, then evaluate managed platforms as workflows scale and operational overhead increases.\n",
105+
"\n",
106+
":::{seealso}\n",
107+
"- [DataJoint Works](https://datajoint.com) — Managed orchestration platform\n",
108+
"- [Populate](050-populate.ipynb) — The underlying automation mechanism\n",
109+
":::"
110+
]
111+
}
112+
],
113+
"metadata": {
114+
"kernelspec": {
115+
"display_name": "Python 3",
116+
"language": "python",
117+
"name": "python3"
118+
},
119+
"language_info": {
120+
"name": "python",
121+
"version": "3.11"
122+
}
123+
},
124+
"nbformat": 4,
125+
"nbformat_minor": 5
126+
}

0 commit comments

Comments
 (0)