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.

Files changed (159) hide show
  1. {pytrilogy-0.0.3.94/pytrilogy.egg-info → pytrilogy-0.0.3.96}/PKG-INFO +184 -136
  2. pytrilogy-0.0.3.96/README.md +422 -0
  3. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96/pytrilogy.egg-info}/PKG-INFO +184 -136
  4. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/SOURCES.txt +6 -1
  5. pytrilogy-0.0.3.96/tests/test_executor.py +64 -0
  6. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parsing.py +1 -1
  7. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/__init__.py +1 -1
  8. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/authoring/__init__.py +61 -43
  9. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/enums.py +13 -0
  10. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/env_processor.py +19 -10
  11. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/environment_helpers.py +111 -0
  12. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/exceptions.py +21 -1
  13. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/functions.py +6 -1
  14. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/graph_models.py +11 -37
  15. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/internal.py +18 -0
  16. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/core.py +3 -0
  17. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/environment.py +28 -0
  18. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/execute.py +7 -0
  19. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_merge_node.py +2 -2
  20. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/query_processor.py +2 -1
  21. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/author.py +18 -3
  22. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/common.py +0 -10
  23. pytrilogy-0.0.3.96/trilogy/core/statements/execute.py +106 -0
  24. pytrilogy-0.0.3.96/trilogy/core/validation/common.py +110 -0
  25. pytrilogy-0.0.3.96/trilogy/core/validation/concept.py +125 -0
  26. pytrilogy-0.0.3.96/trilogy/core/validation/datasource.py +194 -0
  27. pytrilogy-0.0.3.96/trilogy/core/validation/environment.py +71 -0
  28. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/base.py +48 -21
  29. pytrilogy-0.0.3.96/trilogy/dialect/metadata.py +233 -0
  30. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/sql_server.py +3 -1
  31. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/engine.py +25 -7
  32. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/executor.py +94 -162
  33. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/parse_engine.py +34 -3
  34. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/trilogy.lark +11 -5
  35. pytrilogy-0.0.3.94/README.md +0 -374
  36. pytrilogy-0.0.3.94/tests/test_executor.py +0 -32
  37. pytrilogy-0.0.3.94/trilogy/core/statements/execute.py +0 -49
  38. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/LICENSE.md +0 -0
  39. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pyproject.toml +0 -0
  40. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/dependency_links.txt +0 -0
  41. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/entry_points.txt +0 -0
  42. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/requires.txt +0 -0
  43. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/pytrilogy.egg-info/top_level.txt +0 -0
  44. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/setup.cfg +0 -0
  45. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/setup.py +0 -0
  46. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_datatypes.py +0 -0
  47. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_declarations.py +0 -0
  48. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_derived_concepts.py +0 -0
  49. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_discovery_nodes.py +0 -0
  50. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_enums.py +0 -0
  51. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_environment.py +0 -0
  52. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_execute_models.py +0 -0
  53. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_failure.py +0 -0
  54. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_functions.py +0 -0
  55. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_imports.py +0 -0
  56. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_metadata.py +0 -0
  57. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_models.py +0 -0
  58. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_multi_join_assignments.py +0 -0
  59. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parse_engine.py +0 -0
  60. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_parsing_failures.py +0 -0
  61. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_partial_handling.py +0 -0
  62. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_query_processing.py +0 -0
  63. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_query_render.py +0 -0
  64. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_select.py +0 -0
  65. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_show.py +0 -0
  66. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_statements.py +0 -0
  67. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_typing.py +0 -0
  68. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_undefined_concept.py +0 -0
  69. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_user_functions.py +0 -0
  70. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/tests/test_where_clause.py +0 -0
  71. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/constants.py +0 -0
  72. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/__init__.py +0 -0
  73. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/constants.py +0 -0
  74. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/ergonomics.py +0 -0
  75. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/__init__.py +0 -0
  76. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/author.py +0 -0
  77. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/build.py +0 -0
  78. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/build_environment.py +0 -0
  79. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/models/datasource.py +0 -0
  80. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimization.py +0 -0
  81. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/__init__.py +0 -0
  82. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/base_optimization.py +0 -0
  83. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/inline_datasource.py +0 -0
  84. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/optimizations/predicate_pushdown.py +0 -0
  85. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/__init__.py +0 -0
  86. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/concept_strategies_v3.py +0 -0
  87. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_loop.py +0 -0
  88. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_node_factory.py +0 -0
  89. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_utility.py +0 -0
  90. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/discovery_validation.py +0 -0
  91. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/graph_utils.py +0 -0
  92. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/__init__.py +0 -0
  93. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/basic_node.py +0 -0
  94. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/common.py +0 -0
  95. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/constant_node.py +0 -0
  96. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/filter_node.py +0 -0
  97. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/group_node.py +0 -0
  98. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/group_to_node.py +0 -0
  99. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/multiselect_node.py +0 -0
  100. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/node_merge_node.py +0 -0
  101. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/recursive_node.py +0 -0
  102. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/rowset_node.py +0 -0
  103. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_helpers/__init__.py +0 -0
  104. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_helpers/datasource_injection.py +0 -0
  105. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/select_node.py +0 -0
  106. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/synonym_node.py +0 -0
  107. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/union_node.py +0 -0
  108. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/unnest_node.py +0 -0
  109. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/node_generators/window_node.py +0 -0
  110. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/__init__.py +0 -0
  111. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/base_node.py +0 -0
  112. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/filter_node.py +0 -0
  113. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/group_node.py +0 -0
  114. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/merge_node.py +0 -0
  115. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/recursive_node.py +0 -0
  116. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/select_node_v2.py +0 -0
  117. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/union_node.py +0 -0
  118. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/unnest_node.py +0 -0
  119. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/nodes/window_node.py +0 -0
  120. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/processing/utility.py +0 -0
  121. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/__init__.py +0 -0
  122. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/statements/build.py +0 -0
  123. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/core/utility.py +0 -0
  124. {pytrilogy-0.0.3.94/trilogy/dialect → pytrilogy-0.0.3.96/trilogy/core/validation}/__init__.py +0 -0
  125. {pytrilogy-0.0.3.94/trilogy/metadata → pytrilogy-0.0.3.96/trilogy/dialect}/__init__.py +0 -0
  126. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/bigquery.py +0 -0
  127. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/common.py +0 -0
  128. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/config.py +0 -0
  129. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/dataframe.py +0 -0
  130. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/duckdb.py +0 -0
  131. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/enums.py +0 -0
  132. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/postgres.py +0 -0
  133. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/presto.py +0 -0
  134. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/dialect/snowflake.py +0 -0
  135. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/__init__.py +0 -0
  136. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/base_hook.py +0 -0
  137. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/graph_hook.py +0 -0
  138. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/hooks/query_debugger.py +0 -0
  139. {pytrilogy-0.0.3.94/trilogy/parsing → pytrilogy-0.0.3.96/trilogy/metadata}/__init__.py +0 -0
  140. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parser.py +0 -0
  141. {pytrilogy-0.0.3.94/trilogy/scripts → pytrilogy-0.0.3.96/trilogy/parsing}/__init__.py +0 -0
  142. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/common.py +0 -0
  143. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/config.py +0 -0
  144. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/exceptions.py +0 -0
  145. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/helpers.py +0 -0
  146. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/parsing/render.py +0 -0
  147. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/py.typed +0 -0
  148. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/render.py +0 -0
  149. {pytrilogy-0.0.3.94/trilogy/std → pytrilogy-0.0.3.96/trilogy/scripts}/__init__.py +0 -0
  150. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/scripts/trilogy.py +0 -0
  151. /pytrilogy-0.0.3.94/trilogy/compiler.py → /pytrilogy-0.0.3.96/trilogy/std/__init__.py +0 -0
  152. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/date.preql +0 -0
  153. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/display.preql +0 -0
  154. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/geography.preql +0 -0
  155. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/money.preql +0 -0
  156. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/net.preql +0 -0
  157. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/ranking.preql +0 -0
  158. {pytrilogy-0.0.3.94 → pytrilogy-0.0.3.96}/trilogy/std/report.preql +0 -0
  159. {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.94
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
- ## Trilogy
39
+ # Trilogy
40
+ **SQL with superpowers for analytics**
41
+
40
42
  [![Website](https://img.shields.io/badge/INTRO-WEB-orange?)](https://trilogydata.dev/)
41
43
  [![Discord](https://img.shields.io/badge/DISCORD-CHAT-red?logo=discord)](https://discord.gg/Z4QSSuqGEd)
44
+ [![PyPI version](https://badge.fury.io/py/pytrilogy.svg)](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
- ### What Trilogy Gives You
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
- - Speed - write faster, with concise, powerful syntax
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
- Trilogy is especially powerful for data consumption, providing a rich metadata layer that makes creating, interperting, and visualizing queries easy and expressive.
60
+ ## Quick Start
56
61
 
57
62
  > [!TIP]
58
- > You can try Trilogy in a [open-source studio](https://trilogydata.dev/trilogy-studio-core/). More details on the language can be found on the [documentation](https://trilogydata.dev/).
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
- 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.
65
+ **Install locally:**
66
+ ```bash
67
+ pip install pytrilogy
68
+ ```
61
69
 
62
- Installation: `pip install pytrilogy`
70
+ **Your first query:**
71
+ ```sql
72
+ # Save as hello.preql
73
+ import names;
63
74
 
64
- ### Trilogy Looks Like SQL
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/mantainability
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
- ## Hello World
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.trilogy duckdb
214
+ trilogy run hello.preql duckdb
170
215
  ```
171
216
 
172
217
  ![UI Preview](hello-world.png)
173
218
 
174
- ## Backends
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 bigquery example, similar to bigquery [the quickstart](https://cloud.google.com/bigquery/docs/quickstarts/query-public-dataset-console).
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
- After installing trilogy, you can run the trilogy CLI with two required positional arguments; the first the path to a file or a direct command,
248
- and second the dialect to run.
249
-
250
- `trilogy run <cmd or path to trilogy file> <dialect>`
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
- ### Snowflake Args
272
- - account
273
- - username
274
- - password
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
- > [!TIP]
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
- ## More Examples
293
+ **DuckDB:**
294
+ - `--path` - Optional database file path
282
295
 
283
- [Interactive demo](https://trilogydata.dev/demo/).
296
+ **Postgres:**
297
+ - `--host` - Database host
298
+ - `--port` - Database port
299
+ - `--username` - Username
300
+ - `--password` - Password
301
+ - `--database` - Database name
284
302
 
285
- Additional examples can be found in the [public model repository](https://github.com/trilogydata/trilogy-public-models).
303
+ **Snowflake:**
304
+ - `--account` - Snowflake account
305
+ - `--username` - Username
306
+ - `--password` - Password
286
307
 
287
- This is a good place to look for modeling examples.
308
+ ## More Resources
288
309
 
289
- ## Developing
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
- Clone repository and install requirements.txt and requirements-test.txt.
314
+ ## Python API Integration
292
315
 
293
- ## Contributing
316
+ ### Root Imports
294
317
 
295
- Please open an issue first to discuss what you would like to change, and then create a PR against that issue.
318
+ Are stable and should be sufficient for executing code from Trilogy as text.
296
319
 
297
- ## Similar in space
298
- Trilogy combines two aspects; a semantic layer and a query language. Examples of both are linked below:
320
+ ```python
321
+ from pytrilogy import Executor, Dialect
322
+ ```
299
323
 
300
- "semantic layers" are tools for defining an metadata layer above a SQL/warehouse base to enable higher level abstractions.
324
+ ### Authoring Imports
301
325
 
302
- - [metricsflow](https://github.com/dbt-labs/metricflow)
303
- - [cube](https://github.com/cube-js/cube)
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
- "Better SQL" has been a popular space. We believe Trilogy takes a different approach then the following,
307
- but all are worth checking out. Please open PRs/comment for anything missed!
329
+ ```python
330
+ from pytrilogy.authoring import Concept, Function, ...
331
+ ```
308
332
 
309
- - [malloy](https://github.com/malloydata/malloy)
310
- - [preql](https://github.com/erezsh/Preql)
311
- - [PREQL](https://github.com/PRQL/prql)
333
+ ### Other Imports
312
334
 
313
- ## Minimal Syntax Reference
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
- #### IMPORT
337
+ ## Trilogy Syntax Reference
316
338
 
317
- `import [path] as [alias];`
339
+ ### Import
340
+ ```sql
341
+ import [path] as [alias];
342
+ ```
318
343
 
319
- #### CONCEPT
344
+ ### Concepts
320
345
 
321
- Types: `string | int | float | bool | date | datetime | time | numeric(scale, precision) | timestamp | interval | list<[type]> | map<[type], [type]> | struct<name:[type], name:[type]>`;
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
- `key [name] [type];`
349
+ **Key:**
350
+ ```sql
351
+ key [name] [type];
352
+ ```
325
353
 
326
- Property:
327
- `property [key>].[name] [type];`
328
- `property x.y int;`
329
- or
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
- `auto [name] <- [expression];`
336
- `auto x <- y + 1;`
364
+ **Transformation:**
365
+ ```sql
366
+ auto [name] <- [expression];
367
+ auto x <- y + 1;
368
+ ```
337
369
 
338
- #### DATASOURCE
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
- #### SELECT
349
-
350
- Primary acces
382
+ ### Queries
351
383
 
384
+ **Basic SELECT:**
352
385
  ```sql
353
386
  WHERE
354
387
  <concept> = <value>
355
- select
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
- #### CTE/ROWSET
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
- #### PERSIST
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
- #### COPY
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
- #### SHOW
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)