1515from sqlmesh .core .console import configure_console , get_console
1616from sqlmesh .utils import Verbosity
1717from sqlmesh .core .config import load_configs
18+ from sqlmesh .core .config .connection import CONNECTION_CONFIG_TO_TYPE
1819from sqlmesh .core .context import Context
1920from sqlmesh .utils .date import TimeLike
2021from sqlmesh .utils .errors import MissingDependencyError , SQLMeshError
3940)
4041SKIP_CONTEXT_COMMANDS = ("init" , "ui" )
4142
42- ENGINE_DISPLAY_NAME_TO_DIALECT = {
43- "Athena" : "athena" ,
44- "Azure SQL" : "tsql" ,
45- "BigQuery" : "bigquery" ,
46- "ClickHouse" : "clickhouse" ,
47- "Databricks" : "databricks" ,
43+ # These are ordered for user display - do not reorder
44+ ENGINE_DISPLAY_NAME_TO_CONNECTION_TYPE = {
4845 "DuckDB" : "duckdb" ,
49- "GCP Postgres" : "postgres" ,
46+ "Snowflake" : "snowflake" ,
47+ "Databricks" : "databricks" ,
48+ "BigQuery" : "bigquery" ,
5049 "MotherDuck" : "duckdb" ,
51- "MSSQL" : "tsql" ,
52- "MySQL" : "mysql" ,
53- "Postgres" : "postgres" ,
50+ "ClickHouse" : "clickhouse" ,
5451 "Redshift" : "redshift" ,
55- "RisingWave" : "postgres" ,
56- "Snowflake" : "snowflake" ,
5752 "Spark" : "spark" ,
5853 "Trino" : "trino" ,
54+ "Azure SQL" : "azuresql" ,
55+ "MSSQL" : "tsql" ,
56+ "Postgres" : "postgres" ,
57+ "GCP Postgres" : "gcp_postgres" ,
58+ "MySQL" : "mysql" ,
59+ "Athena" : "athena" ,
60+ "RisingWave" : "risingwave" ,
5961}
6062
6163
@@ -201,38 +203,55 @@ def init(
201203
202204 if sql_dialect or project_template == ProjectTemplate .DBT :
203205 init_example_project (
204- ctx .obj ,
206+ path = ctx .obj ,
205207 dialect = sql_dialect ,
208+ engine_type = None ,
206209 template = project_template or ProjectTemplate .DEFAULT ,
207210 pipeline = dlt_pipeline ,
208211 dlt_path = dlt_path ,
209212 )
210- else :
211- import sqlmesh .utils .rich as srich
213+ return
212214
213- console = srich . console
215+ import sqlmesh . utils . rich as srich
214216
215- project_template , sql_dialect , cli_mode = _interactive_init (console , project_template )
216- config_path = init_example_project (
217- ctx .obj ,
218- template = project_template ,
219- dialect = sql_dialect ,
220- cli_mode = cli_mode ,
221- pipeline = dlt_pipeline ,
222- dlt_path = dlt_path ,
223- )
224- console .print (f"""──────────────────────────────
217+ console = srich .console
218+
219+ project_template , engine_type , cli_mode = _interactive_init (console , project_template )
220+ if project_template != ProjectTemplate .DBT :
221+ _check_engine_installed (console , engine_type )
222+
223+ config_path = init_example_project (
224+ path = ctx .obj ,
225+ dialect = None ,
226+ template = project_template ,
227+ engine_type = engine_type ,
228+ cli_mode = cli_mode or InitCliMode .DEFAULT ,
229+ pipeline = dlt_pipeline ,
230+ dlt_path = dlt_path ,
231+ )
232+
233+ next_step_text = {
234+ ProjectTemplate .DEFAULT : f"• Update your gateway connection settings (e.g., username/password) in the project configuration file:\n { config_path } \n Run command in CLI: sqlmesh plan\n (Optional) Explain a plan: sqlmesh plan --explain" ,
235+ ProjectTemplate .DBT : "" ,
236+ }
237+ next_step_text [ProjectTemplate .EMPTY ] = next_step_text [ProjectTemplate .DEFAULT ]
238+
239+ quickstart_text = {
240+ ProjectTemplate .DEFAULT : "Quickstart guide:\n https://sqlmesh.readthedocs.io/en/stable/quickstart/cli/" ,
241+ ProjectTemplate .DBT : "dbt guide:\n https://sqlmesh.readthedocs.io/en/stable/integrations/dbt/" ,
242+ }
243+ quickstart_text [ProjectTemplate .EMPTY ] = quickstart_text [ProjectTemplate .DEFAULT ]
244+
245+ console .print (f"""──────────────────────────────
225246
226247Your SQLMesh project is ready!
227248
228249Next steps:
229- • Update your gateway connection settings (e.g., username/password) in the project configuration file:
230- { config_path }
250+ { next_step_text [project_template ]}
231251• Run command in CLI: sqlmesh plan
232252• (Optional) Explain a plan: sqlmesh plan --explain
233253
234- Quickstart guide:
235- https://sqlmesh.readthedocs.io/en/stable/quickstart/cli/
254+ { quickstart_text [project_template ]}
236255
237256Need help?
238257• Docs: https://sqlmesh.readthedocs.io
@@ -1286,21 +1305,29 @@ def state_import(obj: Context, input_file: Path, replace: bool, no_confirm: bool
12861305
12871306def _interactive_init (
12881307 console : Console , project_template : t .Optional [ProjectTemplate ] = None
1289- ) -> t .Tuple [ProjectTemplate , str , InitCliMode ]:
1308+ ) -> t .Tuple [ProjectTemplate , t . Optional [ str ], t . Optional [ InitCliMode ] ]:
12901309 console .print ("──────────────────────────────" )
12911310 console .print ("Welcome to SQLMesh!" )
12921311
12931312 project_template = _init_template_prompt (console ) if not project_template else project_template
1294- dialect = _init_engine_prompt (console )
1313+
1314+ if project_template == ProjectTemplate .DBT :
1315+ if not Path ("dbt_project.yml" ).exists ():
1316+ raise SQLMeshError (
1317+ "Required file 'dbt_project.yml' not found in the current directory.\n \n Please add it or change directories before running `sqlmesh init` to set up your dbt project with SQLMesh."
1318+ )
1319+ return (project_template , None , None )
1320+
1321+ engine_type = _init_engine_prompt (console )
12951322 cli_mode = _init_cli_mode_prompt (console )
12961323
1297- return (project_template , dialect , cli_mode )
1324+ return (project_template , engine_type , cli_mode )
12981325
12991326
13001327def _init_integer_prompt (
13011328 console : Console , err_msg_entity : str , num_options : int , retry_func : t .Callable [[t .Any ], t .Any ]
13021329) -> int :
1303- err_msg = "\n ERROR: '{option_str}' is not a valid {err_msg_entity} number - please enter a number between 1 and {num_options} or exit with Ctrl+C "
1330+ err_msg = "\n ERROR: '{option_str}' is not a valid {err_msg_entity} number - please enter a number between 1 and {num_options} or exit with control+c "
13041331 option_str = Prompt .ask ("Enter a number" , console = console )
13051332 try :
13061333 option_num = int (option_str )
@@ -1321,11 +1348,11 @@ def _init_integer_prompt(
13211348
13221349
13231350def _init_template_prompt (console : Console ) -> ProjectTemplate :
1351+ # These are ordered for user display - do not reorder
13241352 template_descriptions = {
13251353 ProjectTemplate .DEFAULT .name : "- Create SQLMesh example project models and files" ,
1326- ProjectTemplate .EMPTY .name : " - Create a configuration file and project file directories" ,
13271354 ProjectTemplate .DBT .value : " - You have an existing dbt project and want to run it with SQLMesh" ,
1328- ProjectTemplate .DLT .name : " - You have an existing DLT pipeline and want to load it with SQLMesh " ,
1355+ ProjectTemplate .EMPTY .name : " - Create a SQLMesh configuration file and project directories only " ,
13291356 }
13301357
13311358 console .print ("──────────────────────────────\n " )
@@ -1349,7 +1376,7 @@ def _init_engine_prompt(console: Console) -> str:
13491376 console .print ("Choose your SQL engine:\n " )
13501377
13511378 display_num_to_engine = {}
1352- for i , engine in enumerate (ENGINE_DISPLAY_NAME_TO_DIALECT .keys ()):
1379+ for i , engine in enumerate (ENGINE_DISPLAY_NAME_TO_CONNECTION_TYPE .keys ()):
13531380 console .print (f" \\ [{ i + 1 } ] { ' ' if i < 9 else '' } { engine } " )
13541381 display_num_to_engine [i + 1 ] = engine
13551382 console .print ("" )
@@ -1361,10 +1388,10 @@ def _init_engine_prompt(console: Console) -> str:
13611388 # """)
13621389
13631390 engine_num = _init_integer_prompt (
1364- console , "engine" , len (ENGINE_DISPLAY_NAME_TO_DIALECT ), _init_engine_prompt
1391+ console , "engine" , len (ENGINE_DISPLAY_NAME_TO_CONNECTION_TYPE ), _init_engine_prompt
13651392 )
13661393
1367- return ENGINE_DISPLAY_NAME_TO_DIALECT [display_num_to_engine [engine_num ]]
1394+ return ENGINE_DISPLAY_NAME_TO_CONNECTION_TYPE [display_num_to_engine [engine_num ]]
13681395
13691396
13701397def _init_cli_mode_prompt (console : Console ) -> InitCliMode :
@@ -1387,3 +1414,17 @@ def _init_cli_mode_prompt(console: Console) -> InitCliMode:
13871414 )
13881415
13891416 return InitCliMode (display_num_to_cli_mode [cli_mode_num ].lower ())
1417+
1418+
1419+ def _check_engine_installed (console : Console , engine_type : t .Optional [str ] = None ) -> None :
1420+ if not engine_type :
1421+ return
1422+ connection_config = CONNECTION_CONFIG_TO_TYPE [engine_type ]
1423+
1424+ try :
1425+ connection_config ._connection_factory .fget (None )
1426+ except ModuleNotFoundError :
1427+ install_command = f'pip install "sqlmesh[{ engine_type } ]"'
1428+ raise SQLMeshError (
1429+ f"Unable to load required Python dependencies for the { engine_type .upper ()} engine.\n \n Please run `{ install_command } ` to install them before running `sqlmesh init` again."
1430+ )
0 commit comments