0
# Configuration Management
1
2
Thread-safe configuration system for customizing SQLLineage behavior including default schemas, dialect-specific parsing options, and integration settings. The configuration system supports both environment variables and context-based temporary configuration changes.
3
4
## Capabilities
5
6
### SQLLineageConfig
7
8
Global configuration object providing thread-safe access to configuration settings with support for environment variable overrides and temporary context-based changes.
9
10
```python { .api }
11
class _SQLLineageConfigLoader:
12
def __init__(self) -> None:
13
"""Initialize the configuration loader"""
14
15
def __call__(self, **kwargs) -> "_SQLLineageConfigLoader":
16
"""
17
Create a configuration context manager for temporary changes.
18
19
Parameters:
20
- **kwargs: configuration key-value pairs to set temporarily
21
22
Returns:
23
Context manager for temporary configuration
24
"""
25
26
def __enter__(self) -> None:
27
"""Enter the configuration context"""
28
29
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
30
"""Exit the configuration context and restore previous settings"""
31
32
def __getattr__(self, item: str) -> Any:
33
"""Get configuration value by attribute name"""
34
35
def __setattr__(self, key: str, value: Any) -> None:
36
"""Set configuration value (raises exception - use context manager instead)"""
37
38
# Global configuration instance
39
SQLLineageConfig = _SQLLineageConfigLoader()
40
```
41
42
## Configuration Options
43
44
### Core Configuration Keys
45
46
```python { .api }
47
# Configuration keys and their types/defaults
48
config = {
49
"DIRECTORY": (str, os.path.join(os.path.dirname(__file__), "data")), # Static files directory (resolved dynamically)
50
"DEFAULT_SCHEMA": (str, ""), # Default schema name
51
"TSQL_NO_SEMICOLON": (bool, False), # TSQL mode without semicolon
52
"LATERAL_COLUMN_ALIAS_REFERENCE": (bool, False) # Support lateral column alias references
53
}
54
```
55
56
### Environment Variable Support
57
58
All configuration options can be set via environment variables with the `SQLLINEAGE_` prefix:
59
60
- `SQLLINEAGE_DIRECTORY` - Override default directory
61
- `SQLLINEAGE_DEFAULT_SCHEMA` - Set default schema
62
- `SQLLINEAGE_TSQL_NO_SEMICOLON` - Enable TSQL no-semicolon mode
63
- `SQLLINEAGE_LATERAL_COLUMN_ALIAS_REFERENCE` - Enable lateral column aliases
64
65
## Usage Examples
66
67
### Basic Configuration Access
68
69
```python
70
from sqllineage.config import SQLLineageConfig
71
72
# Access configuration values
73
print("Default schema:", SQLLineageConfig.DEFAULT_SCHEMA)
74
print("Static directory:", SQLLineageConfig.DIRECTORY)
75
print("TSQL no semicolon:", SQLLineageConfig.TSQL_NO_SEMICOLON)
76
```
77
78
### Environment Variable Configuration
79
80
```bash
81
# Set environment variables
82
export SQLLINEAGE_DEFAULT_SCHEMA="analytics"
83
export SQLLINEAGE_TSQL_NO_SEMICOLON="true"
84
```
85
86
```python
87
from sqllineage.config import SQLLineageConfig
88
89
# Configuration will use environment variable values
90
print("Default schema:", SQLLineageConfig.DEFAULT_SCHEMA) # "analytics"
91
print("TSQL mode:", SQLLineageConfig.TSQL_NO_SEMICOLON) # True
92
```
93
94
### Context-Based Configuration
95
96
```python
97
from sqllineage.config import SQLLineageConfig
98
from sqllineage.runner import LineageRunner
99
100
# Temporary configuration change
101
with SQLLineageConfig(DEFAULT_SCHEMA="staging"):
102
# Inside context, DEFAULT_SCHEMA is "staging"
103
sql = "SELECT * FROM customers" # Will be interpreted as staging.customers
104
runner = LineageRunner(sql)
105
print("Tables:", [str(t) for t in runner.source_tables])
106
107
# Outside context, DEFAULT_SCHEMA returns to original value
108
print("Default schema:", SQLLineageConfig.DEFAULT_SCHEMA)
109
```
110
111
### Multiple Configuration Changes
112
113
```python
114
from sqllineage.config import SQLLineageConfig
115
116
# Set multiple configuration options temporarily
117
with SQLLineageConfig(
118
DEFAULT_SCHEMA="production",
119
TSQL_NO_SEMICOLON=True,
120
LATERAL_COLUMN_ALIAS_REFERENCE=True
121
):
122
# Analyze SQL with custom configuration
123
sql = """
124
SELECT
125
customer_id,
126
revenue,
127
revenue * 0.1 as commission
128
FROM sales
129
WHERE commission > 1000
130
"""
131
runner = LineageRunner(sql, dialect="tsql")
132
runner.print_column_lineage()
133
```
134
135
### Schema-Specific Analysis
136
137
```python
138
from sqllineage.config import SQLLineageConfig
139
from sqllineage.runner import LineageRunner
140
141
# Analyze SQL with different default schemas
142
schemas = ["raw", "staging", "production"]
143
144
for schema in schemas:
145
with SQLLineageConfig(DEFAULT_SCHEMA=schema):
146
sql = "INSERT INTO customer_summary SELECT * FROM customer_details"
147
runner = LineageRunner(sql)
148
print(f"Schema {schema}:")
149
print(f" Source: {runner.source_tables}")
150
print(f" Target: {runner.target_tables}")
151
```
152
153
### Dialect-Specific Configuration
154
155
```python
156
from sqllineage.config import SQLLineageConfig
157
158
# Configure for SQL Server T-SQL without semicolon separators
159
with SQLLineageConfig(TSQL_NO_SEMICOLON=True):
160
tsql = """
161
CREATE TABLE #temp AS SELECT * FROM customers
162
INSERT INTO sales_summary
163
SELECT customer_id, SUM(amount) FROM #temp GROUP BY customer_id
164
DROP TABLE #temp
165
"""
166
runner = LineageRunner(tsql, dialect="tsql")
167
print("T-SQL analysis with no-semicolon mode")
168
169
# Configure for databases supporting lateral column references
170
with SQLLineageConfig(LATERAL_COLUMN_ALIAS_REFERENCE=True):
171
sql = """
172
SELECT
173
customer_id,
174
total_amount,
175
total_amount * 0.1 as tax,
176
total_amount + tax as final_amount
177
FROM orders
178
"""
179
runner = LineageRunner(sql, dialect="redshift")
180
runner.print_column_lineage()
181
```
182
183
### Thread Safety
184
185
```python
186
import threading
187
from sqllineage.config import SQLLineageConfig
188
189
def analyze_in_thread(schema_name, sql):
190
with SQLLineageConfig(DEFAULT_SCHEMA=schema_name):
191
runner = LineageRunner(sql)
192
print(f"Thread {schema_name}: {runner.source_tables}")
193
194
# Different threads can have different configurations
195
threads = []
196
for i, schema in enumerate(["dev", "staging", "prod"]):
197
sql = f"SELECT * FROM table_{i}"
198
thread = threading.Thread(target=analyze_in_thread, args=(schema, sql))
199
threads.append(thread)
200
thread.start()
201
202
for thread in threads:
203
thread.join()
204
```
205
206
### Configuration Validation
207
208
```python
209
from sqllineage.config import SQLLineageConfig
210
from sqllineage.exceptions import ConfigException
211
212
try:
213
# Attempting to set configuration directly raises an exception
214
SQLLineageConfig.DEFAULT_SCHEMA = "invalid"
215
except ConfigException as e:
216
print(f"Configuration error: {e}")
217
print("Use context manager instead:")
218
219
with SQLLineageConfig(DEFAULT_SCHEMA="valid"):
220
print("Configuration set successfully")
221
```
222
223
### Custom Configuration Patterns
224
225
```python
226
from sqllineage.config import SQLLineageConfig
227
from sqllineage.runner import LineageRunner
228
229
class AnalysisProfile:
230
def __init__(self, name, default_schema, dialect, tsql_mode=False):
231
self.name = name
232
self.default_schema = default_schema
233
self.dialect = dialect
234
self.tsql_mode = tsql_mode
235
236
def analyze(self, sql):
237
with SQLLineageConfig(
238
DEFAULT_SCHEMA=self.default_schema,
239
TSQL_NO_SEMICOLON=self.tsql_mode
240
):
241
runner = LineageRunner(sql, dialect=self.dialect)
242
return runner
243
244
# Define analysis profiles
245
profiles = {
246
"snowflake_prod": AnalysisProfile("Snowflake Prod", "ANALYTICS", "snowflake"),
247
"sqlserver_dev": AnalysisProfile("SQL Server Dev", "dbo", "tsql", tsql_mode=True),
248
"postgres_staging": AnalysisProfile("PostgreSQL Staging", "staging", "postgres")
249
}
250
251
# Use profiles for analysis
252
sql = "SELECT customer_id, sum(amount) FROM orders GROUP BY customer_id"
253
254
for profile_name, profile in profiles.items():
255
runner = profile.analyze(sql)
256
print(f"{profile.name}: {runner.source_tables}")
257
```
258
259
### Configuration Debugging
260
261
```python
262
from sqllineage.config import SQLLineageConfig
263
264
def debug_configuration():
265
print("Current configuration:")
266
print(f" DIRECTORY: {SQLLineageConfig.DIRECTORY}")
267
print(f" DEFAULT_SCHEMA: {SQLLineageConfig.DEFAULT_SCHEMA}")
268
print(f" TSQL_NO_SEMICOLON: {SQLLineageConfig.TSQL_NO_SEMICOLON}")
269
print(f" LATERAL_COLUMN_ALIAS_REFERENCE: {SQLLineageConfig.LATERAL_COLUMN_ALIAS_REFERENCE}")
270
271
# Debug before and after configuration changes
272
debug_configuration()
273
274
with SQLLineageConfig(DEFAULT_SCHEMA="test", TSQL_NO_SEMICOLON=True):
275
print("\nInside context:")
276
debug_configuration()
277
278
print("\nAfter context:")
279
debug_configuration()
280
```