You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Typed macros in SQLMesh bring the power of type hints from Python, enhancing readability, maintainability, and usability of your SQL macros. These macros enable developers to specify expected types for arguments, making the macros more intuitive and less error-prone.
1050
-
1051
-
### Benefits of Typed Macros
1052
-
1053
-
1.**Improved Readability**: By specifying types, the intent of the macro is clearer to other developers or future you.
1054
-
2.**Reduced Boilerplate**: No need for manual type conversion within the macro function, allowing you to focus on the core logic.
1055
-
3.**Enhanced Autocompletion**: IDEs can provide better autocompletion and documentation based on the specified types.
1056
-
1057
-
### Defining a Typed Macro
1058
-
1059
-
Typed macros in SQLMesh use Python's type hints. Here's a simple example of a typed macro that repeats a string a given number of times:
This macro takes two arguments: `text` of type `str` and `count` of type `int`, and it returns a string. Without type hints, the inputs to the macro would have been two `exp.Literal` objects you would have had to convert to strings and integers manually.
1078
-
1079
-
### Supported Types
1080
-
1081
-
SQLMesh supports common Python types for typed macros including:
1082
-
1083
-
-`str`
1084
-
-`int`
1085
-
-`float`
1086
-
-`bool`
1087
-
-`List[T]` - where `T` is any supported type including sqlglot expressions
1088
-
-`Tuple[T]` - where `T` is any supported type including sqlglot expressions
1089
-
-`Union[T1, T2, ...]` - where `T1`, `T2`, etc. are any supported types including sqlglot expressions
1090
-
1091
-
We also support SQLGlot expressions as type hints, allowing you to ensure inputs are coerced to the desired SQL AST node your intending on working with. Some useful examples include:
1092
-
1093
-
-`exp.Table`
1094
-
-`exp.Column`
1095
-
-`exp.Literal`
1096
-
-`exp.Identifier`
1097
-
1098
-
While these might be obvious examples, you can effectively coerce an input into _any_ SQLGlot expression type, which can be useful for more complex macros. When coercing to more complex types, you will almost certainly need to pass a string literal since expression to expression coercion is limited. When a string literal is passed to a macro that hints at a SQLGlot expression, the string will be parsed using SQLGlot and coerced to the correct type. Failure to coerce to the correct type will result in the original expression being passed to the macro and a warning being logged for the user to address as-needed.
# Coercing to a complex node like `exp.Select` works as expected given a string literal input
1106
-
# SELECT * FROM @stamped('SELECT a, b, c')
1107
-
```
1108
-
1109
-
When coercion fails, there will always be a warning logged but we will not crash. We believe the macro should be flexible by default, meaning the default behavior is preserved if we cannot coerce. Give that, the user can express whatever level of additional checks they want. For example, if you would like to raise an error when the coercion fails, you can use an `assert` statement. For example:
# Raises an error thanks to the users inclusion of the assert, otherwise would pass through the string literal and log a warning
1123
-
# SELECT * FROM @my_macro('SELECT 1 + 1')
1124
-
```
1125
-
1126
-
In using assert this way, you still get the benefits of reducing/removing the boilerplate needed to coerce types; but you **also** get guarantees about the type of the input. This is a useful pattern and is user-defined, so you can use it as you see fit. It ultimately allows you to keep the macro definition clean and focused on the core business logic.
1127
-
1128
-
### Advanced Typed Macros
1129
-
1130
-
You can create more complex macros using advanced Python features like generics. For example, a macro that accepts a list of integers and returns their sum:
Generics can be nested and are resolved recursively allowing for fairly robust type hinting.
1150
-
1151
-
See examples of the coercion function in action in the test suite [here](../../../tests/core/test_macros.py).
1152
-
1153
-
### Conclusion
1154
-
1155
-
Typed macros in SQLMesh not only enhance the development experience by making macros more readable and easier to use but also contribute to more robust and maintainable code. By leveraging Python's type hinting system, developers can create powerful and intuitive macros for their SQL queries, further bridging the gap between SQL and Python.
1156
-
1157
1047
## Mixing macro systems
1158
1048
1159
1049
SQLMesh supports both SQLMesh and [Jinja](./jinja_macros.md) macro systems. We strongly recommend using only one system in a model - if both are present, they may fail or behave in unintuitive ways.
0 commit comments