@@ -204,17 +204,27 @@ that generate static completion files (system-wide bash, zsh completion director
204204Available Commands
205205==================
206206
207- The SQLSpec CLI provides commands for managing database migrations. All commands
208- require a ``--config `` option pointing to your SQLSpec configuration.
207+ The SQLSpec CLI provides commands for managing database migrations. Configure the CLI
208+ using ``--config `` flag, ``SQLSPEC_CONFIG `` environment variable, or ``[tool.sqlspec] ``
209+ section in pyproject.toml.
209210
210211Configuration Loading
211212---------------------
212213
213- The `` --config `` option accepts a dotted path to either :
214+ SQLSpec CLI supports three ways to specify your database configuration, in order of precedence :
214215
215- 1. **A single config object **: ``myapp.config.db_config ``
216- 2. **A config list **: ``myapp.config.configs ``
217- 3. **A callable function **: ``myapp.config.get_configs() ``
216+ 1. **CLI Flag ** (``--config ``) - Explicit override for one-off commands
217+ 2. **Environment Variable ** (``SQLSPEC_CONFIG ``) - Convenient for development workflows
218+ 3. **pyproject.toml ** (``[tool.sqlspec] ``) - Project-wide default configuration
219+
220+ The ``--config `` option and ``SQLSPEC_CONFIG `` environment variable accept:
221+
222+ - **A single config object **: ``myapp.config.db_config ``
223+ - **A config list **: ``myapp.config.configs ``
224+ - **A callable function **: ``myapp.config.get_configs() ``
225+ - **Multiple config paths (comma-separated) **: ``myapp.config.primary_config,myapp.config.analytics_config ``
226+
227+ Each config path is resolved independently, and if a callable returns a list of configs, all configs are collected.
218228
219229Example configuration file (``myapp/config.py ``):
220230
@@ -225,13 +235,128 @@ Example configuration file (``myapp/config.py``):
225235 :end-before: # end-example
226236 :caption: `configuration loading `
227237
238+ Config Discovery Methods
239+ ^^^^^^^^^^^^^^^^^^^^^^^^
240+
241+ **Method 1: CLI Flag (Highest Priority) **
242+
243+ .. code-block :: bash
244+
245+ sqlspec --config myapp.config.get_configs upgrade head
246+
247+ Use for one-off commands or to override other config sources.
248+
249+ **Method 2: Environment Variable **
250+
251+ .. code-block :: bash
252+
253+ export SQLSPEC_CONFIG=myapp.config.get_configs
254+ sqlspec upgrade head # Uses environment variable
255+
256+ Convenient for development. Add to your shell profile:
257+
258+ .. code-block :: bash
259+
260+ # ~/.bashrc or ~/.zshrc
261+ export SQLSPEC_CONFIG=myapp.config.get_configs
262+
263+ Multiple configs (comma-separated):
264+
265+ .. code-block :: bash
266+
267+ export SQLSPEC_CONFIG=" app.db.primary_config,app.db.analytics_config"
268+
269+ **Method 3: pyproject.toml (Project Default) **
270+
271+ .. code-block :: toml
272+
273+ [tool.sqlspec]
274+ config = "myapp.config.get_configs"
275+
276+ Best for team projects - config is version controlled.
277+
278+ Multiple configs (array):
279+
280+ .. code-block :: toml
281+
282+ [tool.sqlspec]
283+ config = [
284+ "myapp.config.primary_config",
285+ "myapp.config.analytics_config"
286+ ]
287+
288+ **Precedence: ** CLI flag > Environment variable > pyproject.toml
289+
290+ If no config is found from any source, SQLSpec will show a helpful error message with examples.
291+
292+ Multi-Config Resolution Details
293+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
294+
295+ When using comma-separated config paths or list format in pyproject.toml, SQLSpec:
296+
297+ 1. **Resolves each path independently **: Each dotted path is imported and resolved
298+ 2. **Flattens callable results **: If a callable returns a list, all configs are collected
299+ 3. **Deduplicates by bind_key **: Later configs override earlier ones with the same ``bind_key ``
300+ 4. **Validates final list **: Empty config lists result in an error
301+
302+ **Deduplication Example: **
303+
304+ .. code-block :: bash
305+
306+ # If primary_config has bind_key="db" and backup_config has bind_key="db"
307+ export SQLSPEC_CONFIG=" app.primary_config,app.backup_config"
308+
309+ # Result: Only backup_config is used (last wins)
310+
311+ **Combined callable and list: **
312+
313+ .. code-block :: python
314+
315+ # myapp/config.py
316+ def get_all_configs ():
317+ """ Returns list of configs."""
318+ return [primary_config, analytics_config]
319+
320+ single_config = AsyncpgConfig(bind_key = " backup" , ... )
321+
322+ .. code-block :: bash
323+
324+ # This resolves to 3 configs: primary, analytics, and backup
325+ export SQLSPEC_CONFIG=" myapp.config.get_all_configs,myapp.config.single_config"
326+
327+ **Deduplication with callables: **
328+
329+ .. code-block :: python
330+
331+ # myapp/config.py
332+ primary = AsyncpgConfig(bind_key = " db" , ... )
333+ updated = AsyncpgConfig(bind_key = " db" , ... ) # Same bind_key
334+
335+ def get_primary ():
336+ return primary
337+
338+ def get_updated ():
339+ return updated
340+
341+ .. code-block :: bash
342+
343+ # Only updated config is used (last wins for bind_key="db")
344+ sqlspec --config " myapp.config.get_primary,myapp.config.get_updated" upgrade
345+
228346 Global Options
229347--------------
230348
231349``--config PATH ``
232- **Required **. Dotted path to SQLSpec config(s) or callable function.
350+ Dotted path to SQLSpec config(s) or callable function. Supports comma-separated
351+ multiple paths. Optional when using environment variable or pyproject.toml config discovery.
352+
353+ Examples:
233354
234- Example: ``--config myapp.config.get_configs ``
355+ - Single config: ``--config myapp.config.db_config ``
356+ - Callable: ``--config myapp.config.get_configs ``
357+ - Multiple paths: ``--config "myapp.config.primary_config,myapp.config.analytics_config" ``
358+
359+ Configs with duplicate ``bind_key `` values are deduplicated (last wins).
235360
236361``--validate-config ``
237362 Validate configuration before executing migrations. Shows loaded configs
@@ -746,6 +871,41 @@ Multi-Config Operations
746871When you have multiple database configurations, SQLSpec provides options to manage
747872them collectively or selectively.
748873
874+ Quick Reference: Multi-Config Patterns
875+ ---------------------------------------
876+
877+ .. list-table ::
878+ :header-rows: 1
879+ :widths: 30 35 35
880+
881+ * - Pattern
882+ - Example
883+ - Behavior
884+ * - Single config
885+ - ``--config "app.config.db" ``
886+ - Load one config
887+ * - Config list
888+ - ``--config "app.config.configs" ``
889+ - Load all configs in list
890+ * - Callable returning list
891+ - ``--config "app.config.get_configs" ``
892+ - Call function, load returned configs
893+ * - Comma-separated paths
894+ - ``--config "app.config.db1,app.config.db2" ``
895+ - Load multiple configs, deduplicate by bind_key
896+ * - Env var (comma-separated)
897+ - ``SQLSPEC_CONFIG="app.config.db1,app.config.db2" ``
898+ - Same as comma-separated CLI flag
899+ * - pyproject.toml (list)
900+ - ``config = ["app.config.db1", "app.config.db2"] ``
901+ - Load all paths in array
902+ * - Mixed callables and configs
903+ - ``--config "app.config.get_configs,app.config.backup" ``
904+ - Flatten callable results + direct configs
905+ * - Duplicate bind_key
906+ - ``--config "app.config.old,app.config.new" ``
907+ - Later config overrides (new wins)
908+
749909Scenario: Multiple Databases
750910-----------------------------
751911
@@ -892,6 +1052,38 @@ Best Practices
8921052
8931053 sqlspec --config myapp.config upgrade --dry-run
8941054
1055+ 7. **Use Unique bind_key for Multi-Config **
1056+
1057+ When managing multiple databases, always specify unique ``bind_key `` values:
1058+
1059+ .. code-block :: python
1060+
1061+ # Good - unique bind_keys
1062+ configs = [
1063+ AsyncpgConfig(bind_key = " primary" , ... ),
1064+ AsyncpgConfig(bind_key = " analytics" , ... ),
1065+ ]
1066+
1067+ # Problematic - configs will overwrite each other
1068+ configs = [
1069+ AsyncpgConfig(bind_key = " db" , ... ), # Same key
1070+ AsyncmyConfig(bind_key = " db" , ... ), # Will override above
1071+ ]
1072+
1073+ 8. **Prefer pyproject.toml for Team Projects **
1074+
1075+ Store config paths in version control for consistency:
1076+
1077+ .. code-block :: toml
1078+
1079+ [tool.sqlspec]
1080+ config = [
1081+ "myapp.config.primary_db",
1082+ "myapp.config.analytics_db"
1083+ ]
1084+
1085+ Team members automatically use the same config without manual setup.
1086+
8951087Framework Integration
8961088=====================
8971089
0 commit comments