pytrilogy 0.0.3.6__tar.gz → 0.0.3.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pytrilogy might be problematic. Click here for more details.

Files changed (129) hide show
  1. {pytrilogy-0.0.3.6/pytrilogy.egg-info → pytrilogy-0.0.3.7}/PKG-INFO +1 -1
  2. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7/pytrilogy.egg-info}/PKG-INFO +1 -1
  3. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pytrilogy.egg-info/SOURCES.txt +1 -0
  4. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/__init__.py +1 -1
  5. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/functions.py +26 -6
  6. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/datasource.py +6 -0
  7. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/config.py +9 -0
  8. pytrilogy-0.0.3.7/trilogy/dialect/dataframe.py +42 -0
  9. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/enums.py +12 -1
  10. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/engine.py +11 -4
  11. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/executor.py +10 -2
  12. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/LICENSE.md +0 -0
  13. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/README.md +0 -0
  14. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pyproject.toml +0 -0
  15. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pytrilogy.egg-info/dependency_links.txt +0 -0
  16. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pytrilogy.egg-info/entry_points.txt +0 -0
  17. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pytrilogy.egg-info/requires.txt +0 -0
  18. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/pytrilogy.egg-info/top_level.txt +0 -0
  19. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/setup.cfg +0 -0
  20. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/setup.py +0 -0
  21. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_datatypes.py +0 -0
  22. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_declarations.py +0 -0
  23. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_derived_concepts.py +0 -0
  24. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_discovery_nodes.py +0 -0
  25. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_enums.py +0 -0
  26. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_environment.py +0 -0
  27. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_executor.py +0 -0
  28. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_functions.py +0 -0
  29. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_imports.py +0 -0
  30. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_metadata.py +0 -0
  31. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_models.py +0 -0
  32. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_multi_join_assignments.py +0 -0
  33. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_parse_engine.py +0 -0
  34. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_parsing.py +0 -0
  35. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_partial_handling.py +0 -0
  36. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_query_processing.py +0 -0
  37. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_select.py +0 -0
  38. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_show.py +0 -0
  39. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_statements.py +0 -0
  40. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_undefined_concept.py +0 -0
  41. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/tests/test_where_clause.py +0 -0
  42. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/authoring/__init__.py +0 -0
  43. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/compiler.py +0 -0
  44. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/constants.py +0 -0
  45. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/__init__.py +0 -0
  46. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/constants.py +0 -0
  47. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/enums.py +0 -0
  48. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/env_processor.py +0 -0
  49. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/environment_helpers.py +0 -0
  50. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/ergonomics.py +0 -0
  51. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/exceptions.py +0 -0
  52. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/graph_models.py +0 -0
  53. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/internal.py +0 -0
  54. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/__init__.py +0 -0
  55. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/author.py +0 -0
  56. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/build.py +0 -0
  57. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/build_environment.py +0 -0
  58. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/core.py +0 -0
  59. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/environment.py +0 -0
  60. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/models/execute.py +0 -0
  61. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimization.py +0 -0
  62. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimizations/__init__.py +0 -0
  63. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimizations/base_optimization.py +0 -0
  64. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimizations/inline_constant.py +0 -0
  65. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimizations/inline_datasource.py +0 -0
  66. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  67. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/__init__.py +0 -0
  68. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  69. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/graph_utils.py +0 -0
  70. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/__init__.py +0 -0
  71. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  72. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/common.py +0 -0
  73. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  74. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/group_node.py +0 -0
  75. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  76. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  77. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  78. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  79. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  80. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  81. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/select_merge_node.py +0 -0
  82. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/select_node.py +0 -0
  83. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  84. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/union_node.py +0 -0
  85. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  86. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/node_generators/window_node.py +0 -0
  87. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/__init__.py +0 -0
  88. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/base_node.py +0 -0
  89. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/filter_node.py +0 -0
  90. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/group_node.py +0 -0
  91. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/merge_node.py +0 -0
  92. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  93. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/union_node.py +0 -0
  94. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  95. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/nodes/window_node.py +0 -0
  96. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/processing/utility.py +0 -0
  97. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/query_processor.py +0 -0
  98. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/statements/__init__.py +0 -0
  99. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/statements/author.py +0 -0
  100. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/statements/build.py +0 -0
  101. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/statements/common.py +0 -0
  102. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/core/statements/execute.py +0 -0
  103. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/__init__.py +0 -0
  104. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/base.py +0 -0
  105. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/bigquery.py +0 -0
  106. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/common.py +0 -0
  107. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/duckdb.py +0 -0
  108. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/postgres.py +0 -0
  109. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/presto.py +0 -0
  110. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/snowflake.py +0 -0
  111. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/dialect/sql_server.py +0 -0
  112. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/hooks/__init__.py +0 -0
  113. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/hooks/base_hook.py +0 -0
  114. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/hooks/graph_hook.py +0 -0
  115. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/hooks/query_debugger.py +0 -0
  116. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/metadata/__init__.py +0 -0
  117. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parser.py +0 -0
  118. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/__init__.py +0 -0
  119. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/common.py +0 -0
  120. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/config.py +0 -0
  121. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/exceptions.py +0 -0
  122. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/helpers.py +0 -0
  123. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/parse_engine.py +0 -0
  124. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/render.py +0 -0
  125. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/parsing/trilogy.lark +0 -0
  126. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/py.typed +0 -0
  127. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/scripts/__init__.py +0 -0
  128. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/scripts/trilogy.py +0 -0
  129. {pytrilogy-0.0.3.6 → pytrilogy-0.0.3.7}/trilogy/utility.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytrilogy
3
- Version: 0.0.3.6
3
+ Version: 0.0.3.7
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytrilogy
3
- Version: 0.0.3.6
3
+ Version: 0.0.3.7
4
4
  Summary: Declarative, typed query language that compiles to SQL.
5
5
  Home-page:
6
6
  Author:
@@ -103,6 +103,7 @@ trilogy/dialect/base.py
103
103
  trilogy/dialect/bigquery.py
104
104
  trilogy/dialect/common.py
105
105
  trilogy/dialect/config.py
106
+ trilogy/dialect/dataframe.py
106
107
  trilogy/dialect/duckdb.py
107
108
  trilogy/dialect/enums.py
108
109
  trilogy/dialect/postgres.py
@@ -4,6 +4,6 @@ from trilogy.dialect.enums import Dialects
4
4
  from trilogy.executor import Executor
5
5
  from trilogy.parser import parse
6
6
 
7
- __version__ = "0.0.3.6"
7
+ __version__ = "0.0.3.7"
8
8
 
9
9
  __all__ = ["parse", "Executor", "Dialects", "Environment", "CONFIG"]
@@ -503,32 +503,52 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
503
503
  arg_count=1,
504
504
  ),
505
505
  FunctionType.ADD: FunctionConfig(
506
- valid_inputs={DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
506
+ valid_inputs={
507
+ DataType.INTEGER,
508
+ DataType.FLOAT,
509
+ DataType.NUMBER,
510
+ DataType.NUMERIC,
511
+ },
507
512
  output_purpose=Purpose.PROPERTY,
508
513
  output_type=DataType.INTEGER,
509
514
  arg_count=InfiniteFunctionArgs,
510
515
  ),
511
516
  FunctionType.SUBTRACT: FunctionConfig(
512
- valid_inputs={DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
517
+ valid_inputs={
518
+ DataType.INTEGER,
519
+ DataType.FLOAT,
520
+ DataType.NUMBER,
521
+ DataType.NUMERIC,
522
+ },
513
523
  output_purpose=Purpose.PROPERTY,
514
524
  output_type=DataType.INTEGER,
515
525
  arg_count=InfiniteFunctionArgs,
516
526
  ),
517
527
  FunctionType.MULTIPLY: FunctionConfig(
518
- valid_inputs={DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
528
+ valid_inputs={
529
+ DataType.INTEGER,
530
+ DataType.FLOAT,
531
+ DataType.NUMBER,
532
+ DataType.NUMERIC,
533
+ },
519
534
  output_purpose=Purpose.PROPERTY,
520
535
  output_type=DataType.INTEGER,
521
536
  arg_count=InfiniteFunctionArgs,
522
537
  ),
523
538
  FunctionType.DIVIDE: FunctionConfig(
524
- valid_inputs={DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
539
+ valid_inputs={
540
+ DataType.INTEGER,
541
+ DataType.FLOAT,
542
+ DataType.NUMBER,
543
+ DataType.NUMERIC,
544
+ },
525
545
  output_purpose=Purpose.PROPERTY,
526
546
  output_type=DataType.INTEGER,
527
547
  arg_count=InfiniteFunctionArgs,
528
548
  ),
529
549
  FunctionType.MOD: FunctionConfig(
530
550
  valid_inputs=[
531
- {DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
551
+ {DataType.INTEGER, DataType.FLOAT, DataType.NUMBER, DataType.NUMERIC},
532
552
  {DataType.INTEGER},
533
553
  ],
534
554
  output_purpose=Purpose.PROPERTY,
@@ -537,7 +557,7 @@ FUNCTION_REGISTRY: dict[FunctionType, FunctionConfig] = {
537
557
  ),
538
558
  FunctionType.ROUND: FunctionConfig(
539
559
  valid_inputs=[
540
- {DataType.INTEGER, DataType.FLOAT, DataType.NUMBER},
560
+ {DataType.INTEGER, DataType.FLOAT, DataType.NUMBER, DataType.NUMERIC},
541
561
  {DataType.INTEGER},
542
562
  ],
543
563
  output_purpose=Purpose.PROPERTY,
@@ -117,6 +117,12 @@ class Datasource(HasUUID, Namespaced, BaseModel):
117
117
  where: Optional[WhereClause] = None
118
118
  non_partial_for: Optional[WhereClause] = None
119
119
 
120
+ @property
121
+ def safe_address(self) -> str:
122
+ if isinstance(self.address, Address):
123
+ return self.address.location
124
+ return self.address
125
+
120
126
  def __eq__(self, other):
121
127
  if not isinstance(other, Datasource):
122
128
  return False
@@ -1,3 +1,6 @@
1
+ from pandas import DataFrame
2
+
3
+
1
4
  class DialectConfig:
2
5
  def __init__(self):
3
6
  pass
@@ -104,3 +107,9 @@ class TrinoConfig(PrestoConfig):
104
107
  if self.schema:
105
108
  return f"trino://{self.username}:{self.password}@{self.host}:{self.port}/{self.catalog}/{self.schema}"
106
109
  return f"trino://{self.username}:{self.password}@{self.host}:{self.port}/{self.catalog}"
110
+
111
+
112
+ class DataFrameConfig(DuckDBConfig):
113
+ def __init__(self, dataframes: dict[str, DataFrame]):
114
+ super().__init__()
115
+ self.dataframes = dataframes
@@ -0,0 +1,42 @@
1
+ from typing import Any
2
+
3
+ from pandas import DataFrame
4
+ from sqlalchemy import text
5
+
6
+ from trilogy.core.models.environment import Environment
7
+ from trilogy.dialect.duckdb import DuckDBDialect
8
+ from trilogy.engine import ExecutionEngine
9
+
10
+
11
+ class DataframeDialect(DuckDBDialect):
12
+ pass
13
+
14
+
15
+ class DataframeConnectionWrapper(ExecutionEngine):
16
+ def __init__(self, engine: ExecutionEngine, dataframes: dict[str, DataFrame]):
17
+ self.engine = engine
18
+ self.dataframes = dataframes
19
+ self.connection = None
20
+
21
+ def setup(self, env: Environment, connection):
22
+ self._register_dataframes(env, connection)
23
+
24
+ def _register_dataframes(self, env: Environment, connection):
25
+ for ds in env.datasources.values():
26
+ if ds.safe_address in self.dataframes:
27
+ connection.execute(
28
+ text("register(:name, :df)"),
29
+ {"name": ds.safe_address, "df": self.dataframes[ds.safe_address]},
30
+ )
31
+ else:
32
+ raise ValueError(
33
+ f"Dataframe {ds.safe_address} not found in dataframes on connection config, have {self.dataframes.keys()}"
34
+ )
35
+ pass
36
+
37
+ def add_dataframe(self, name: str, df: DataFrame, connection, env: Environment):
38
+ self.dataframes[name] = df
39
+ self._register_dataframes(env, connection)
40
+
41
+ def connect(self) -> Any:
42
+ return self.engine.connect()
@@ -16,7 +16,7 @@ def default_factory(conf: DialectConfig, config_type):
16
16
 
17
17
  if not isinstance(conf, config_type):
18
18
  raise TypeError(
19
- f"Invalid dialect configuration for type {type(config_type).__name__}"
19
+ f"Invalid dialect configuration for type {type(config_type).__name__}, is {type(conf)}"
20
20
  )
21
21
  if conf.connect_args:
22
22
  return create_engine(
@@ -33,6 +33,7 @@ class Dialects(Enum):
33
33
  TRINO = "trino"
34
34
  POSTGRES = "postgres"
35
35
  SNOWFLAKE = "snowflake"
36
+ DATAFRAME = "dataframe"
36
37
 
37
38
  @classmethod
38
39
  def _missing_(cls, value):
@@ -88,6 +89,16 @@ class Dialects(Enum):
88
89
  from trilogy.dialect.config import TrinoConfig
89
90
 
90
91
  return _engine_factory(conf, TrinoConfig)
92
+ elif self == Dialects.DATAFRAME:
93
+ from trilogy.dialect.config import DataFrameConfig
94
+ from trilogy.dialect.dataframe import DataframeConnectionWrapper
95
+
96
+ if not conf:
97
+ conf = DataFrameConfig(dataframes={})
98
+
99
+ base = _engine_factory(conf, DataFrameConfig)
100
+
101
+ return DataframeConnectionWrapper(base, dataframes=conf.dataframes)
91
102
  else:
92
103
  raise ValueError(
93
104
  f"Unsupported dialect {self} for default engine creation; create one explicitly."
@@ -1,7 +1,9 @@
1
- from typing import Protocol
1
+ from typing import Any, Protocol
2
2
 
3
3
  from sqlalchemy.engine import Connection, CursorResult, Engine
4
4
 
5
+ from trilogy.core.models.environment import Environment
6
+
5
7
 
6
8
  class EngineResult(Protocol):
7
9
  pass
@@ -13,7 +15,7 @@ class EngineResult(Protocol):
13
15
  class EngineConnection(Protocol):
14
16
  pass
15
17
 
16
- def execute(self, statement: str) -> EngineResult:
18
+ def execute(self, statement: str, parameters: Any | None = None) -> EngineResult:
17
19
  pass
18
20
 
19
21
 
@@ -23,6 +25,9 @@ class ExecutionEngine(Protocol):
23
25
  def connect(self) -> EngineConnection:
24
26
  pass
25
27
 
28
+ def setup(self, env: Environment, connection):
29
+ pass
30
+
26
31
 
27
32
  ### Begin default SQLAlchemy implementation
28
33
  class SqlAlchemyResult(EngineResult):
@@ -37,8 +42,10 @@ class SqlAlchemyConnection(EngineConnection):
37
42
  def __init__(self, connection: Connection):
38
43
  self.connection = connection
39
44
 
40
- def execute(self, statement: str) -> SqlAlchemyResult:
41
- return SqlAlchemyResult(self.connection.execute(statement))
45
+ def execute(
46
+ self, statement: str, parameters: Any | None = None
47
+ ) -> SqlAlchemyResult:
48
+ return SqlAlchemyResult(self.connection.execute(statement, parameters))
42
49
 
43
50
 
44
51
  class SqlAlchemyEngine(ExecutionEngine):
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from typing import Any, Generator, List, Optional, Protocol
5
5
 
6
6
  from sqlalchemy import text
7
- from sqlalchemy.engine import CursorResult, Engine
7
+ from sqlalchemy.engine import CursorResult
8
8
 
9
9
  from trilogy.constants import logger
10
10
  from trilogy.core.enums import FunctionType, Granularity, IOType
@@ -33,6 +33,7 @@ from trilogy.core.statements.execute import (
33
33
  )
34
34
  from trilogy.dialect.base import BaseDialect
35
35
  from trilogy.dialect.enums import Dialects
36
+ from trilogy.engine import ExecutionEngine
36
37
  from trilogy.hooks.base_hook import BaseHook
37
38
  from trilogy.parser import parse_text
38
39
 
@@ -71,7 +72,7 @@ class Executor(object):
71
72
  def __init__(
72
73
  self,
73
74
  dialect: Dialects,
74
- engine: Engine,
75
+ engine: ExecutionEngine,
75
76
  environment: Optional[Environment] = None,
76
77
  hooks: List[BaseHook] | None = None,
77
78
  ):
@@ -109,9 +110,16 @@ class Executor(object):
109
110
  from trilogy.dialect.snowflake import SnowflakeDialect
110
111
 
111
112
  self.generator = SnowflakeDialect()
113
+ elif self.dialect == Dialects.DATAFRAME:
114
+ from trilogy.dialect.dataframe import DataframeDialect
115
+
116
+ self.generator = DataframeDialect()
112
117
  else:
113
118
  raise ValueError(f"Unsupported dialect {self.dialect}")
114
119
  self.connection = self.engine.connect()
120
+ # TODO: make generic
121
+ if self.dialect == Dialects.DATAFRAME:
122
+ self.engine.setup(self.environment, self.connection)
115
123
 
116
124
  def execute_statement(self, statement) -> Optional[CursorResult]:
117
125
  if not isinstance(
File without changes
File without changes
File without changes
File without changes
File without changes