pytrilogy 0.0.3.94__tar.gz → 0.0.3.96__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.
- {pytrilogy-0.0.3.94/pytrilogy.egg-info → pytrilogy-0.0.3.96}/PKG-INFO +184 -136
- pytrilogy-0.0.3.96/README.md +422 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96/pytrilogy.egg-info}/PKG-INFO +184 -136
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/SOURCES.txt +6 -1
- pytrilogy-0.0.3.96/tests/test_executor.py +64 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parsing.py +1 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/__init__.py +1 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/authoring/__init__.py +61 -43
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/enums.py +13 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/env_processor.py +19 -10
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/environment_helpers.py +111 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/exceptions.py +21 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/functions.py +6 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/graph_models.py +11 -37
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/internal.py +18 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/core.py +3 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/environment.py +28 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/execute.py +7 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_merge_node.py +2 -2
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/query_processor.py +2 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/author.py +18 -3
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/common.py +0 -10
- pytrilogy-0.0.3.96/trilogy/core/statements/execute.py +106 -0
- pytrilogy-0.0.3.96/trilogy/core/validation/common.py +110 -0
- pytrilogy-0.0.3.96/trilogy/core/validation/concept.py +125 -0
- pytrilogy-0.0.3.96/trilogy/core/validation/datasource.py +194 -0
- pytrilogy-0.0.3.96/trilogy/core/validation/environment.py +71 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/base.py +48 -21
- pytrilogy-0.0.3.96/trilogy/dialect/metadata.py +233 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/sql_server.py +3 -1
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/engine.py +25 -7
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/executor.py +94 -162
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/parse_engine.py +34 -3
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/trilogy.lark +11 -5
- pytrilogy-0.0.3.94/README.md +0 -374
- pytrilogy-0.0.3.94/tests/test_executor.py +0 -32
- pytrilogy-0.0.3.94/trilogy/core/statements/execute.py +0 -49
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/LICENSE.md +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pyproject.toml +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/dependency_links.txt +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/entry_points.txt +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/requires.txt +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/top_level.txt +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/setup.cfg +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/setup.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_datatypes.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_declarations.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_derived_concepts.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_discovery_nodes.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_enums.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_environment.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_execute_models.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_failure.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_functions.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_imports.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_metadata.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_models.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_multi_join_assignments.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parse_engine.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parsing_failures.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_partial_handling.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_query_processing.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_query_render.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_select.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_show.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_statements.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_typing.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_undefined_concept.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_user_functions.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_where_clause.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/constants.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/constants.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/ergonomics.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/author.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/build.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/build_environment.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/datasource.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimization.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/base_optimization.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/inline_datasource.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/concept_strategies_v3.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_loop.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_node_factory.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_utility.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_validation.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/graph_utils.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/basic_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/common.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/constant_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/filter_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/group_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/union_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/window_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/base_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/filter_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/group_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/merge_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/recursive_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/union_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/unnest_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/window_node.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/utility.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/build.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/utility.py +0 -0
- {pytrilogy-0.0.3.94/trilogy/dialect → pytrilogy-0.0.3.96/trilogy/core/validation}/__init__.py +0 -0
- {pytrilogy-0.0.3.94/trilogy/metadata → pytrilogy-0.0.3.96/trilogy/dialect}/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/bigquery.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/common.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/config.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/dataframe.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/duckdb.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/enums.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/postgres.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/presto.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/snowflake.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/base_hook.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/graph_hook.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/query_debugger.py +0 -0
- {pytrilogy-0.0.3.94/trilogy/parsing → pytrilogy-0.0.3.96/trilogy/metadata}/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parser.py +0 -0
- {pytrilogy-0.0.3.94/trilogy/scripts → pytrilogy-0.0.3.96/trilogy/parsing}/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/common.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/config.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/exceptions.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/helpers.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/render.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/py.typed +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/render.py +0 -0
- {pytrilogy-0.0.3.94/trilogy/std → pytrilogy-0.0.3.96/trilogy/scripts}/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/scripts/trilogy.py +0 -0
- /pytrilogy-0.0.3.94/trilogy/compiler.py → /pytrilogy-0.0.3.96/trilogy/std/__init__.py +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/date.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/display.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/geography.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/money.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/net.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/ranking.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/report.preql +0 -0
- {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/utility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytrilogy
|
|
3
|
-
Version: 0.0.3.
|
|
3
|
+
Version: 0.0.3.96
|
|
4
4
|
Summary: Declarative, typed query language that compiles to SQL.
|
|
5
5
|
Home-page:
|
|
6
6
|
Author:
|
|
@@ -36,32 +36,64 @@ Dynamic: provides-extra
|
|
|
36
36
|
Dynamic: requires-dist
|
|
37
37
|
Dynamic: summary
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
# Trilogy
|
|
40
|
+
**SQL with superpowers for analytics**
|
|
41
|
+
|
|
40
42
|
[](https://trilogydata.dev/)
|
|
41
43
|
[](https://discord.gg/Z4QSSuqGEd)
|
|
44
|
+
[](https://badge.fury.io/py/pytrilogy)
|
|
42
45
|
|
|
43
|
-
The Trilogy language is an experiment in better SQL for analytics - a streamlined SQL that replaces tables/joins with a lightweight semantic binding layer and provides easy reuse and composability. It compiles to SQL - making it easy to debug or integrate into existing workflows - and can be run against any supported SQL backend.
|
|
46
|
+
The Trilogy language is an experiment in better SQL for analytics - a streamlined SQL that replaces tables/joins with a lightweight semantic binding layer and provides easy reuse and composability. It compiles to SQL - making it easy to debug or integrate into existing workflows - and can be run against any supported SQL backend.
|
|
44
47
|
|
|
45
48
|
[pytrilogy](https://github.com/trilogy-data/pytrilogy) is the reference implementation, written in Python.
|
|
46
49
|
|
|
47
|
-
|
|
50
|
+
## What Trilogy Gives You
|
|
51
|
+
|
|
52
|
+
- **Speed** - write faster, with concise, powerful syntax
|
|
53
|
+
- **Efficiency** - write less SQL, and reuse what you do
|
|
54
|
+
- **Fearless refactoring** - change models without breaking queries
|
|
55
|
+
- **Testability** - built-in testing patterns with query fixtures
|
|
56
|
+
- **Easy to use** - for humans and LLMs alike
|
|
48
57
|
|
|
49
|
-
|
|
50
|
-
- Efficiency - write less SQL, and reuse what you do
|
|
51
|
-
- Fearless refactoring
|
|
52
|
-
- Testability
|
|
53
|
-
- Easy to use for humans and LLMs
|
|
58
|
+
Trilogy is especially powerful for data consumption, providing a rich metadata layer that makes creating, interpreting, and visualizing queries easy and expressive.
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
## Quick Start
|
|
56
61
|
|
|
57
62
|
> [!TIP]
|
|
58
|
-
>
|
|
63
|
+
> **Try it now:** [Open-source studio](https://trilogydata.dev/trilogy-studio-core/) | [Interactive demo](https://trilogydata.dev/demo/) | [Documentation](https://trilogydata.dev/)
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
**Install locally:**
|
|
66
|
+
```bash
|
|
67
|
+
pip install pytrilogy
|
|
68
|
+
```
|
|
61
69
|
|
|
62
|
-
|
|
70
|
+
**Your first query:**
|
|
71
|
+
```sql
|
|
72
|
+
# Save as hello.preql
|
|
73
|
+
import names;
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
const top_names <- ['Elvis', 'Elvira', 'Elrond', 'Sam'];
|
|
76
|
+
|
|
77
|
+
def initcap(word) -> upper(substring(word, 1, 1)) || substring(word, 2, len(word));
|
|
78
|
+
|
|
79
|
+
WHERE
|
|
80
|
+
@initcap(name) in top_names
|
|
81
|
+
SELECT
|
|
82
|
+
name,
|
|
83
|
+
sum(births) as name_count
|
|
84
|
+
ORDER BY
|
|
85
|
+
name_count desc
|
|
86
|
+
LIMIT 10;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Run it:**
|
|
90
|
+
```bash
|
|
91
|
+
trilogy run hello.preql duckdb
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
We recommend starting with the studio to explore Trilogy. For integration, `pytrilogy` can be run locally to parse and execute trilogy model [.preql] files using the `trilogy` CLI tool, or can be run in python by importing the `trilogy` package.
|
|
95
|
+
|
|
96
|
+
## Trilogy Looks Like SQL
|
|
65
97
|
|
|
66
98
|
```sql
|
|
67
99
|
import names;
|
|
@@ -79,26 +111,40 @@ ORDER BY
|
|
|
79
111
|
name_count desc
|
|
80
112
|
LIMIT 10;
|
|
81
113
|
```
|
|
114
|
+
|
|
82
115
|
## Goals
|
|
116
|
+
|
|
83
117
|
Versus SQL, Trilogy aims to:
|
|
84
118
|
|
|
85
|
-
Keep
|
|
119
|
+
**Keep:**
|
|
86
120
|
- Correctness
|
|
87
121
|
- Accessibility
|
|
88
122
|
|
|
89
|
-
Improve
|
|
123
|
+
**Improve:**
|
|
90
124
|
- Simplicity
|
|
91
|
-
- Refactoring/
|
|
125
|
+
- Refactoring/maintainability
|
|
92
126
|
- Reusability
|
|
93
127
|
|
|
94
|
-
Maintain
|
|
128
|
+
**Maintain:**
|
|
95
129
|
- Acceptable performance
|
|
96
130
|
|
|
97
|
-
Remove
|
|
131
|
+
**Remove:**
|
|
98
132
|
- Lower-level procedural features
|
|
99
133
|
- Transactional optimizations/non-analytics features
|
|
100
134
|
|
|
101
|
-
##
|
|
135
|
+
## Backend Support
|
|
136
|
+
|
|
137
|
+
| Backend | Status | Notes |
|
|
138
|
+
|---------|--------|-------|
|
|
139
|
+
| **BigQuery** | Core | Full support |
|
|
140
|
+
| **DuckDB** | Core | Full support |
|
|
141
|
+
| **Snowflake** | Core | Full support |
|
|
142
|
+
| **SQL Server** | Experimental | Limited testing |
|
|
143
|
+
| **Presto** | Experimental | Limited testing |
|
|
144
|
+
|
|
145
|
+
## Examples
|
|
146
|
+
|
|
147
|
+
### Hello World
|
|
102
148
|
|
|
103
149
|
Save the following code in a file named `hello.preql`
|
|
104
150
|
|
|
@@ -161,50 +207,33 @@ WHERE
|
|
|
161
207
|
SELECT
|
|
162
208
|
sentences.text
|
|
163
209
|
;
|
|
164
|
-
|
|
165
210
|
```
|
|
166
|
-
Run the following from the directory the file is in.
|
|
167
211
|
|
|
212
|
+
**Run it:**
|
|
168
213
|
```bash
|
|
169
|
-
trilogy run hello.
|
|
214
|
+
trilogy run hello.preql duckdb
|
|
170
215
|
```
|
|
171
216
|
|
|
172
217
|

|
|
173
218
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
The current Trilogy implementation supports these backends:
|
|
177
|
-
|
|
178
|
-
### Core
|
|
179
|
-
- Bigquery
|
|
180
|
-
- DuckDB
|
|
181
|
-
- Snowflake
|
|
182
|
-
|
|
183
|
-
### Experimental
|
|
184
|
-
- SQL Server
|
|
185
|
-
- Presto
|
|
186
|
-
|
|
187
|
-
## Basic Example - Python
|
|
219
|
+
### Python SDK Usage
|
|
188
220
|
|
|
189
221
|
Trilogy can be run directly in python through the core SDK. Trilogy code can be defined and parsed inline or parsed out of files.
|
|
190
222
|
|
|
191
|
-
A
|
|
223
|
+
A BigQuery example, similar to the [BigQuery quickstart](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console):
|
|
192
224
|
|
|
193
225
|
```python
|
|
194
|
-
|
|
195
226
|
from trilogy import Dialects, Environment
|
|
196
227
|
|
|
197
228
|
environment = Environment()
|
|
198
229
|
|
|
199
230
|
environment.parse('''
|
|
200
|
-
|
|
201
231
|
key name string;
|
|
202
232
|
key gender string;
|
|
203
233
|
key state string;
|
|
204
234
|
key year int;
|
|
205
235
|
key yearly_name_count int; int;
|
|
206
236
|
|
|
207
|
-
|
|
208
237
|
datasource usa_names(
|
|
209
238
|
name:name,
|
|
210
239
|
number:yearly_name_count,
|
|
@@ -213,13 +242,11 @@ datasource usa_names(
|
|
|
213
242
|
state:state
|
|
214
243
|
)
|
|
215
244
|
address `bigquery-public-data.usa_names.usa_1910_2013`;
|
|
245
|
+
''')
|
|
216
246
|
|
|
217
|
-
'''
|
|
218
|
-
)
|
|
219
247
|
executor = Dialects.BIGQUERY.default_executor(environment=environment)
|
|
220
248
|
|
|
221
|
-
results = executor.execute_text(
|
|
222
|
-
'''
|
|
249
|
+
results = executor.execute_text('''
|
|
223
250
|
WHERE
|
|
224
251
|
name = 'Elvis'
|
|
225
252
|
SELECT
|
|
@@ -228,9 +255,8 @@ SELECT
|
|
|
228
255
|
ORDER BY
|
|
229
256
|
name_count desc
|
|
230
257
|
LIMIT 10;
|
|
231
|
-
'''
|
|
258
|
+
''')
|
|
232
259
|
|
|
233
|
-
)
|
|
234
260
|
# multiple queries can result from one text batch
|
|
235
261
|
for row in results:
|
|
236
262
|
# get results for first query
|
|
@@ -239,105 +265,113 @@ for row in results:
|
|
|
239
265
|
print(x)
|
|
240
266
|
```
|
|
241
267
|
|
|
242
|
-
|
|
243
|
-
## Basic Example - CLI
|
|
268
|
+
### CLI Usage
|
|
244
269
|
|
|
245
270
|
Trilogy can be run through a CLI tool, also named 'trilogy'.
|
|
246
271
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
To pass arguments to a backend, append additional --<option> flags after specifying the dialect.
|
|
253
|
-
|
|
254
|
-
Example:
|
|
255
|
-
`trilogy run "key x int; datasource test_source ( i:x) grain(in) address test; select x;" duckdb --path <path/to/database>`
|
|
256
|
-
|
|
257
|
-
### Bigquery Args
|
|
258
|
-
N/A, only supports default auth. In python you can pass in a custom client.
|
|
259
|
-
<TODO> support arbitrary cred paths.
|
|
260
|
-
|
|
261
|
-
### DuckDB Args
|
|
262
|
-
- path <optional>
|
|
263
|
-
|
|
264
|
-
### Postgres Args
|
|
265
|
-
- host
|
|
266
|
-
- port
|
|
267
|
-
- username
|
|
268
|
-
- password
|
|
269
|
-
- database
|
|
272
|
+
**Basic syntax:**
|
|
273
|
+
```bash
|
|
274
|
+
trilogy run <cmd or path to trilogy file> <dialect>
|
|
275
|
+
```
|
|
270
276
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
277
|
+
**With backend options:**
|
|
278
|
+
```bash
|
|
279
|
+
trilogy run "key x int; datasource test_source(i:x) grain(x) address test; select x;" duckdb --path <path/to/database>
|
|
280
|
+
```
|
|
275
281
|
|
|
282
|
+
**Format code:**
|
|
283
|
+
```bash
|
|
284
|
+
trilogy fmt <path to trilogy file>
|
|
285
|
+
```
|
|
276
286
|
|
|
277
|
-
|
|
278
|
-
> The CLI can also be used for formatting. Trilogy has a default formatting style that should always be adhered to. `trilogy fmt <path to trilogy file>`
|
|
287
|
+
#### Backend Configuration
|
|
279
288
|
|
|
289
|
+
**BigQuery:**
|
|
290
|
+
- Uses applicationdefault authentication (TODO: support arbitrary credential paths)
|
|
291
|
+
- In Python, you can pass a custom client
|
|
280
292
|
|
|
281
|
-
|
|
293
|
+
**DuckDB:**
|
|
294
|
+
- `--path` - Optional database file path
|
|
282
295
|
|
|
283
|
-
|
|
296
|
+
**Postgres:**
|
|
297
|
+
- `--host` - Database host
|
|
298
|
+
- `--port` - Database port
|
|
299
|
+
- `--username` - Username
|
|
300
|
+
- `--password` - Password
|
|
301
|
+
- `--database` - Database name
|
|
284
302
|
|
|
285
|
-
|
|
303
|
+
**Snowflake:**
|
|
304
|
+
- `--account` - Snowflake account
|
|
305
|
+
- `--username` - Username
|
|
306
|
+
- `--password` - Password
|
|
286
307
|
|
|
287
|
-
|
|
308
|
+
## More Resources
|
|
288
309
|
|
|
289
|
-
|
|
310
|
+
- [Interactive demo](https://trilogydata.dev/demo/)
|
|
311
|
+
- [Public model repository](https://github.com/trilogydata/trilogy-public-models) - Great place for modeling examples
|
|
312
|
+
- [Full documentation](https://trilogydata.dev/)
|
|
290
313
|
|
|
291
|
-
|
|
314
|
+
## Python API Integration
|
|
292
315
|
|
|
293
|
-
|
|
316
|
+
### Root Imports
|
|
294
317
|
|
|
295
|
-
|
|
318
|
+
Are stable and should be sufficient for executing code from Trilogy as text.
|
|
296
319
|
|
|
297
|
-
|
|
298
|
-
|
|
320
|
+
```python
|
|
321
|
+
from pytrilogy import Executor, Dialect
|
|
322
|
+
```
|
|
299
323
|
|
|
300
|
-
|
|
324
|
+
### Authoring Imports
|
|
301
325
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
- [zillion](https://github.com/totalhack/zillion)
|
|
326
|
+
Are also stable, and should be used for cases which programatically generate Trilogy statements without a base text format
|
|
327
|
+
or need to process/transform parsed code in more complicated ways.
|
|
305
328
|
|
|
306
|
-
|
|
307
|
-
|
|
329
|
+
```python
|
|
330
|
+
from pytrilogy.authoring import Concept, Function, ...
|
|
331
|
+
```
|
|
308
332
|
|
|
309
|
-
|
|
310
|
-
- [preql](https://github.com/erezsh/Preql)
|
|
311
|
-
- [PREQL](https://github.com/PRQL/prql)
|
|
333
|
+
### Other Imports
|
|
312
334
|
|
|
313
|
-
|
|
335
|
+
Are likely to be unstable. Open an issue if you need to take dependencies on other modules outside those two paths.
|
|
314
336
|
|
|
315
|
-
|
|
337
|
+
## Trilogy Syntax Reference
|
|
316
338
|
|
|
317
|
-
|
|
339
|
+
### Import
|
|
340
|
+
```sql
|
|
341
|
+
import [path] as [alias];
|
|
342
|
+
```
|
|
318
343
|
|
|
319
|
-
|
|
344
|
+
### Concepts
|
|
320
345
|
|
|
321
|
-
Types
|
|
346
|
+
**Types:**
|
|
347
|
+
`string | int | float | bool | date | datetime | time | numeric(scale, precision) | timestamp | interval | array<[type]> | map<[type], [type]> | struct<name:[type], name:[type]>`
|
|
322
348
|
|
|
323
|
-
Key
|
|
324
|
-
|
|
349
|
+
**Key:**
|
|
350
|
+
```sql
|
|
351
|
+
key [name] [type];
|
|
352
|
+
```
|
|
325
353
|
|
|
326
|
-
Property
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
`property <[key](,[key])?>.<name> [type];`
|
|
331
|
-
`property <x,y>.z int;`
|
|
354
|
+
**Property:**
|
|
355
|
+
```sql
|
|
356
|
+
property [key].[name] [type];
|
|
357
|
+
property x.y int;
|
|
332
358
|
|
|
359
|
+
# or multi-key
|
|
360
|
+
property <[key],[key]>.[name] [type];
|
|
361
|
+
property <x,y>.z int;
|
|
362
|
+
```
|
|
333
363
|
|
|
334
|
-
Transformation
|
|
335
|
-
|
|
336
|
-
|
|
364
|
+
**Transformation:**
|
|
365
|
+
```sql
|
|
366
|
+
auto [name] <- [expression];
|
|
367
|
+
auto x <- y + 1;
|
|
368
|
+
```
|
|
337
369
|
|
|
338
|
-
|
|
370
|
+
### Datasource
|
|
339
371
|
```sql
|
|
340
372
|
datasource <name>(
|
|
373
|
+
<column_and_concept_with_same_name>,
|
|
374
|
+
# or a mapping from column to concept
|
|
341
375
|
<column>:<concept>,
|
|
342
376
|
<column>:<concept>,
|
|
343
377
|
)
|
|
@@ -345,14 +379,13 @@ grain(<concept>, <concept>)
|
|
|
345
379
|
address <table>;
|
|
346
380
|
```
|
|
347
381
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
Primary acces
|
|
382
|
+
### Queries
|
|
351
383
|
|
|
384
|
+
**Basic SELECT:**
|
|
352
385
|
```sql
|
|
353
386
|
WHERE
|
|
354
387
|
<concept> = <value>
|
|
355
|
-
|
|
388
|
+
SELECT
|
|
356
389
|
<concept>,
|
|
357
390
|
<concept>+1 -> <alias>,
|
|
358
391
|
...
|
|
@@ -363,10 +396,7 @@ ORDER BY
|
|
|
363
396
|
;
|
|
364
397
|
```
|
|
365
398
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
Reusable virtual set of rows. Useful for windows, filtering.
|
|
369
|
-
|
|
399
|
+
**CTEs/Rowsets:**
|
|
370
400
|
```sql
|
|
371
401
|
with <alias> as
|
|
372
402
|
WHERE
|
|
@@ -376,25 +406,18 @@ select
|
|
|
376
406
|
<concept>+1 -> <alias>,
|
|
377
407
|
...
|
|
378
408
|
|
|
379
|
-
|
|
380
409
|
select <alias>.<concept>;
|
|
381
|
-
|
|
382
410
|
```
|
|
383
411
|
|
|
412
|
+
### Data Operations
|
|
384
413
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
Store output of a query in a warehouse table
|
|
388
|
-
|
|
414
|
+
**Persist to table:**
|
|
389
415
|
```sql
|
|
390
416
|
persist <alias> as <table_name> from
|
|
391
417
|
<select>;
|
|
392
418
|
```
|
|
393
419
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
Currently supported target types are <CSV>, though backend support may vary.
|
|
397
|
-
|
|
420
|
+
**Export to file:**
|
|
398
421
|
```sql
|
|
399
422
|
COPY INTO <TARGET_TYPE> '<target_path>' FROM SELECT
|
|
400
423
|
<concept>, ...
|
|
@@ -403,10 +426,35 @@ ORDER BY
|
|
|
403
426
|
;
|
|
404
427
|
```
|
|
405
428
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
Return generated SQL without executing.
|
|
409
|
-
|
|
429
|
+
**Show generated SQL:**
|
|
410
430
|
```sql
|
|
411
431
|
show <select>;
|
|
412
432
|
```
|
|
433
|
+
|
|
434
|
+
**Validate Model**
|
|
435
|
+
```sql
|
|
436
|
+
validate all
|
|
437
|
+
validate concepts abc,def...
|
|
438
|
+
validate datasources abc,def...
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
## Contributing
|
|
443
|
+
|
|
444
|
+
Clone repository and install requirements.txt and requirements-test.txt.
|
|
445
|
+
|
|
446
|
+
Please open an issue first to discuss what you would like to change, and then create a PR against that issue.
|
|
447
|
+
|
|
448
|
+
## Similar Projects
|
|
449
|
+
|
|
450
|
+
Trilogy combines two aspects: a semantic layer and a query language. Examples of both are linked below:
|
|
451
|
+
|
|
452
|
+
**Semantic layers** - tools for defining a metadata layer above SQL/warehouse to enable higher level abstractions:
|
|
453
|
+
- [MetricFlow](https://github.com/dbt-labs/metricflow)
|
|
454
|
+
- [Cube](https://github.com/cube-js/cube)
|
|
455
|
+
- [Zillion](https://github.com/totalhack/zillion)
|
|
456
|
+
|
|
457
|
+
**Better SQL** has been a popular space. We believe Trilogy takes a different approach than the following, but all are worth checking out. Please open PRs/comment for anything missed!
|
|
458
|
+
- [Malloy](https://github.com/malloydata/malloy)
|
|
459
|
+
- [Preql](https://github.com/erezsh/Preql)
|
|
460
|
+
- [PRQL](https://github.com/PRQL/prql)
|