Skip to content

Commit 742a7a2

Browse files
docs: Separate config from notebooks, add PostgreSQL compatibility
Changes: - Remove environment variable configuration from notebooks (DataJoint reads DJ_* env vars automatically) - Add conftest.py to configure DataJoint for pytest runs - Fix boolean aggregation in 04-queries.ipynb to work on both backends (use CASE WHEN instead of sum(boolean)) - Add PostgreSQL skip to json-type.ipynb (requires MySQL JSON functions) Test results: - MySQL: 21/21 passed - PostgreSQL: 20/20 passed, 1 skipped (json-type) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6abdc0c commit 742a7a2

22 files changed

Lines changed: 57 additions & 22 deletions

conftest.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
Pytest configuration for notebook tests.
3+
4+
Configures DataJoint from environment variables before any tests run.
5+
This separates configuration from workflow execution.
6+
7+
Usage:
8+
# MySQL (default)
9+
DJ_HOST=localhost DJ_USER=root DJ_PASS=tutorial pytest --nbmake ...
10+
11+
# PostgreSQL
12+
DJ_HOST=localhost DJ_PORT=5432 DJ_USER=datajoint DJ_PASS=tutorial DJ_BACKEND=postgresql pytest --nbmake ...
13+
"""
14+
15+
import os
16+
17+
18+
def pytest_configure(config):
19+
"""Configure DataJoint from environment variables before tests run."""
20+
import datajoint as dj
21+
22+
# Database connection settings
23+
if os.getenv('DJ_HOST'):
24+
dj.config['database.host'] = os.getenv('DJ_HOST')
25+
if os.getenv('DJ_PORT'):
26+
dj.config['database.port'] = int(os.getenv('DJ_PORT'))
27+
if os.getenv('DJ_USER'):
28+
dj.config['database.user'] = os.getenv('DJ_USER')
29+
if os.getenv('DJ_PASS'):
30+
dj.config['database.password'] = os.getenv('DJ_PASS')
31+
if os.getenv('DJ_BACKEND'):
32+
dj.config['database.backend'] = os.getenv('DJ_BACKEND')
33+
34+
# Display settings for notebooks
35+
dj.config['display.limit'] = 8

src/how-to/model-relationships.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
]
3232
}
3333
],
34-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('howto_relationships')\nschema.drop(prompt=False)\nschema = dj.Schema('howto_relationships')"
34+
"source": "import datajoint as dj\n\nschema = dj.Schema('howto_relationships')\nschema.drop(prompt=False)\nschema = dj.Schema('howto_relationships')"
3535
},
3636
{
3737
"cell_type": "markdown",

src/how-to/read-diagrams.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
]
3737
}
3838
],
39-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('howto_diagrams')\nschema.drop(prompt=False)\nschema = dj.Schema('howto_diagrams')"
39+
"source": "import datajoint as dj\n\nschema = dj.Schema('howto_diagrams')\nschema.drop(prompt=False)\nschema = dj.Schema('howto_diagrams')"
4040
},
4141
{
4242
"cell_type": "markdown",

src/tutorials/advanced/custom-codecs.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
]
3636
}
3737
],
38-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nimport numpy as np\n\nschema = dj.Schema('tutorial_codecs')"
38+
"source": "import datajoint as dj\n\nimport numpy as np\n\nschema = dj.Schema('tutorial_codecs')"
3939
},
4040
{
4141
"cell_type": "markdown",

src/tutorials/advanced/distributed.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
]
3737
}
3838
],
39-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nimport numpy as np\nimport time\n\nschema = dj.Schema('tutorial_distributed')\n\n# Clean up from previous runs\nschema.drop(prompt=False)\nschema = dj.Schema('tutorial_distributed')"
39+
"source": "import datajoint as dj\n\nimport numpy as np\nimport time\n\nschema = dj.Schema('tutorial_distributed')\n\n# Clean up from previous runs\nschema.drop(prompt=False)\nschema = dj.Schema('tutorial_distributed')"
4040
},
4141
{
4242
"cell_type": "markdown",

src/tutorials/advanced/json-type.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
}
4343
},
4444
"outputs": [],
45-
"source": "import datajoint as dj\nimport os\n\n# Configure database connection from environment variables (for CI/testing)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\n# Check if running against PostgreSQL - skip this MySQL-specific tutorial"
45+
"source": "import datajoint as dj\n\n# Skip this tutorial when running against PostgreSQL\n# (requires MySQL 8.0+ for JSON_VALUE function)\nimport pytest\nif dj.config.database.backend == 'postgresql':\n pytest.skip(\"JSON tutorial requires MySQL 8.0+ (uses MySQL-specific JSON functions)\", allow_module_level=True)"
4646
},
4747
{
4848
"cell_type": "markdown",

src/tutorials/advanced/sql-comparison.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
}
3535
},
3636
"outputs": [],
37-
"source": "import datajoint as dj\nimport os\n\n# Configure database connection from environment variables (for CI/testing)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('tutorial_sql_comparison')"
37+
"source": "import datajoint as dj\n\n# Configure database connection from environment variables (for CI/testing)\n\nschema = dj.Schema('tutorial_sql_comparison')"
3838
},
3939
{
4040
"cell_type": "markdown",

src/tutorials/basics/01-first-pipeline.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
}
4040
},
4141
"outputs": [],
42-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('tutorial_first_pipeline')"
42+
"source": "import datajoint as dj\n\nschema = dj.Schema('tutorial_first_pipeline')"
4343
},
4444
{
4545
"cell_type": "markdown",

src/tutorials/basics/02-schema-design.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
]
3737
}
3838
],
39-
"source": "import datajoint as dj\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('tutorial_design')"
39+
"source": "import datajoint as dj\n\nschema = dj.Schema('tutorial_design')"
4040
},
4141
{
4242
"cell_type": "markdown",

src/tutorials/basics/03-data-entry.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
}
3131
},
3232
"outputs": [],
33-
"source": "import datajoint as dj\nimport numpy as np\nimport os\n\n# Configure from environment variables (for testing with different backends)\nif os.getenv('DJ_HOST'):\n dj.config['database.host'] = os.getenv('DJ_HOST')\nif os.getenv('DJ_PORT'):\n dj.config['database.port'] = int(os.getenv('DJ_PORT'))\nif os.getenv('DJ_USER'):\n dj.config['database.user'] = os.getenv('DJ_USER')\nif os.getenv('DJ_PASS'):\n dj.config['database.password'] = os.getenv('DJ_PASS')\n\nschema = dj.Schema('tutorial_data_entry')"
33+
"source": "import datajoint as dj\nimport numpy as np\n\nschema = dj.Schema('tutorial_data_entry')"
3434
},
3535
{
3636
"cell_type": "code",

0 commit comments

Comments
 (0)