1313
1414from sqlspec .core .cache import CacheKey , get_cache_config , get_default_cache
1515from sqlspec .core .statement import SQL
16- from sqlspec .exceptions import (
17- MissingDependencyError ,
18- SQLFileNotFoundError ,
19- SQLFileParseError ,
20- StorageOperationFailedError ,
21- )
16+ from sqlspec .exceptions import SQLFileNotFoundError , SQLFileParseError , StorageOperationFailedError
2217from sqlspec .storage .registry import storage_registry as default_storage_registry
2318from sqlspec .utils .correlation import CorrelationContext
2419from sqlspec .utils .logging import get_logger
20+ from sqlspec .utils .text import slugify
2521
2622if TYPE_CHECKING :
2723 from sqlspec .storage .registry import StorageRegistry
@@ -60,7 +56,7 @@ def _normalize_query_name(name: str) -> str:
6056 Returns:
6157 Normalized query name suitable as Python identifier.
6258 """
63- return TRIM_SPECIAL_CHARS . sub ( "" , name ). replace ( "-" , "_" )
59+ return slugify ( name , separator = "_" )
6460
6561
6662def _normalize_dialect (dialect : str ) -> str :
@@ -76,19 +72,6 @@ def _normalize_dialect(dialect: str) -> str:
7672 return DIALECT_ALIASES .get (normalized , normalized )
7773
7874
79- def _normalize_dialect_for_sqlglot (dialect : str ) -> str :
80- """Normalize dialect name for SQLGlot compatibility.
81-
82- Args:
83- dialect: Dialect name from SQL file or parameter.
84-
85- Returns:
86- SQLGlot-compatible dialect name.
87- """
88- normalized = dialect .lower ().strip ()
89- return DIALECT_ALIASES .get (normalized , normalized )
90-
91-
9275class NamedStatement :
9376 """Represents a parsed SQL statement with metadata.
9477
@@ -218,8 +201,7 @@ def _calculate_file_checksum(self, path: Union[str, Path]) -> str:
218201 SQLFileParseError: If file cannot be read.
219202 """
220203 try :
221- content = self ._read_file_content (path )
222- return hashlib .md5 (content .encode (), usedforsecurity = False ).hexdigest ()
204+ return hashlib .md5 (self ._read_file_content (path ).encode (), usedforsecurity = False ).hexdigest ()
223205 except Exception as e :
224206 raise SQLFileParseError (str (path ), str (path ), e ) from e
225207
@@ -253,19 +235,13 @@ def _read_file_content(self, path: Union[str, Path]) -> str:
253235 SQLFileNotFoundError: If file does not exist.
254236 SQLFileParseError: If file cannot be read or parsed.
255237 """
256-
257238 path_str = str (path )
258239
259240 try :
260241 backend = self .storage_registry .get (path )
261242 return backend .read_text (path_str , encoding = self .encoding )
262243 except KeyError as e :
263244 raise SQLFileNotFoundError (path_str ) from e
264- except MissingDependencyError :
265- try :
266- return path .read_text (encoding = self .encoding ) # type: ignore[union-attr]
267- except FileNotFoundError as e :
268- raise SQLFileNotFoundError (path_str ) from e
269245 except StorageOperationFailedError as e :
270246 if "not found" in str (e ).lower () or "no such file" in str (e ).lower ():
271247 raise SQLFileNotFoundError (path_str ) from e
@@ -419,8 +395,7 @@ def _load_directory(self, dir_path: Path) -> int:
419395 for file_path in sql_files :
420396 relative_path = file_path .relative_to (dir_path )
421397 namespace_parts = relative_path .parent .parts
422- namespace = "." .join (namespace_parts ) if namespace_parts else None
423- self ._load_single_file (file_path , namespace )
398+ self ._load_single_file (file_path , "." .join (namespace_parts ) if namespace_parts else None )
424399 return len (sql_files )
425400
426401 def _load_single_file (self , file_path : Union [str , Path ], namespace : Optional [str ]) -> None :
@@ -533,44 +508,6 @@ def add_named_sql(self, name: str, sql: str, dialect: "Optional[str]" = None) ->
533508 self ._queries [normalized_name ] = statement
534509 self ._query_to_file [normalized_name ] = "<directly added>"
535510
536- def get_sql (self , name : str ) -> "SQL" :
537- """Get a SQL object by statement name.
538-
539- Args:
540- name: Name of the statement (from -- name: in SQL file).
541- Hyphens in names are converted to underscores.
542-
543- Returns:
544- SQL object ready for execution.
545-
546- Raises:
547- SQLFileNotFoundError: If statement name not found.
548- """
549- correlation_id = CorrelationContext .get ()
550-
551- safe_name = _normalize_query_name (name )
552-
553- if safe_name not in self ._queries :
554- available = ", " .join (sorted (self ._queries .keys ())) if self ._queries else "none"
555- logger .error (
556- "Statement not found: %s" ,
557- name ,
558- extra = {
559- "statement_name" : name ,
560- "safe_name" : safe_name ,
561- "available_statements" : len (self ._queries ),
562- "correlation_id" : correlation_id ,
563- },
564- )
565- raise SQLFileNotFoundError (name , path = f"Statement '{ name } ' not found. Available statements: { available } " )
566-
567- parsed_statement = self ._queries [safe_name ]
568- sqlglot_dialect = None
569- if parsed_statement .dialect :
570- sqlglot_dialect = _normalize_dialect_for_sqlglot (parsed_statement .dialect )
571-
572- return SQL (parsed_statement .sql , dialect = sqlglot_dialect )
573-
574511 def get_file (self , path : Union [str , Path ]) -> "Optional[SQLFile]" :
575512 """Get a loaded SQLFile object by path.
576513
@@ -659,3 +596,41 @@ def get_query_text(self, name: str) -> str:
659596 if safe_name not in self ._queries :
660597 raise SQLFileNotFoundError (name )
661598 return self ._queries [safe_name ].sql
599+
600+ def get_sql (self , name : str ) -> "SQL" :
601+ """Get a SQL object by statement name.
602+
603+ Args:
604+ name: Name of the statement (from -- name: in SQL file).
605+ Hyphens in names are converted to underscores.
606+
607+ Returns:
608+ SQL object ready for execution.
609+
610+ Raises:
611+ SQLFileNotFoundError: If statement name not found.
612+ """
613+ correlation_id = CorrelationContext .get ()
614+
615+ safe_name = _normalize_query_name (name )
616+
617+ if safe_name not in self ._queries :
618+ available = ", " .join (sorted (self ._queries .keys ())) if self ._queries else "none"
619+ logger .error (
620+ "Statement not found: %s" ,
621+ name ,
622+ extra = {
623+ "statement_name" : name ,
624+ "safe_name" : safe_name ,
625+ "available_statements" : len (self ._queries ),
626+ "correlation_id" : correlation_id ,
627+ },
628+ )
629+ raise SQLFileNotFoundError (name , path = f"Statement '{ name } ' not found. Available statements: { available } " )
630+
631+ parsed_statement = self ._queries [safe_name ]
632+ sqlglot_dialect = None
633+ if parsed_statement .dialect :
634+ sqlglot_dialect = _normalize_dialect (parsed_statement .dialect )
635+
636+ return SQL (parsed_statement .sql , dialect = sqlglot_dialect )
0 commit comments