diff --git a/examples/experimental/dagster-components/dagster_components/__init__.py b/examples/experimental/dagster-components/dagster_components/__init__.py index 4438df21a7f13..0f4d31450868a 100644 --- a/examples/experimental/dagster-components/dagster_components/__init__.py +++ b/examples/experimental/dagster-components/dagster_components/__init__.py @@ -6,6 +6,7 @@ from dagster_components.core.component_defs_builder import ( build_defs_from_toplevel_components_folder as build_defs_from_toplevel_components_folder, ) +from dagster_components.impls.dbt_project import DbtProjectComponent from dagster_components.impls.pipes_subprocess_script_collection import ( PipesSubprocessScriptCollection, ) @@ -14,4 +15,5 @@ __component_registry__ = { "pipes_subprocess_script_collection": PipesSubprocessScriptCollection, "sling_replication": SlingReplicationComponent, + "dbt_project": DbtProjectComponent, } diff --git a/examples/experimental/dagster-components/dagster_components/impls/dbt_project.py b/examples/experimental/dagster-components/dagster_components/impls/dbt_project.py new file mode 100644 index 0000000000000..008dd6e5c1cbc --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components/impls/dbt_project.py @@ -0,0 +1,45 @@ +from dagster._core.definitions.definitions_class import Definitions +from dagster._utils import pushd +from dagster_dbt import DbtCliResource, DbtProject, dbt_assets +from dagster_embedded_elt.sling.resources import AssetExecutionContext +from pydantic import BaseModel, TypeAdapter +from typing_extensions import Self + +from dagster_components import Component, ComponentLoadContext +from dagster_components.core.component_decl_builder import ComponentDeclNode, YamlComponentDecl + + +class DbtProjectParams(BaseModel): + dbt: DbtCliResource + + +class DbtProjectComponent(Component): + params_schema = DbtProjectParams + + def __init__(self, dbt_resource: DbtCliResource): + self.dbt_resource = dbt_resource + + @classmethod + def registered_name(cls) -> str: + return "dbt_project" + + @classmethod + def from_decl_node(cls, context: ComponentLoadContext, decl_node: ComponentDeclNode) -> Self: + assert isinstance(decl_node, YamlComponentDecl) + + # all paths should be resolved relative to the directory we're in + with pushd(str(decl_node.path)): + loaded_params = TypeAdapter(cls.params_schema).validate_python( + decl_node.defs_file_model.component_params + ) + return cls(dbt_resource=loaded_params.dbt) + + def build_defs(self, context: ComponentLoadContext) -> Definitions: + project = DbtProject(self.dbt_resource.project_dir) + project.prepare_if_dev() + + @dbt_assets(manifest=project.manifest_path, project=project) + def _fn(context: AssetExecutionContext, dbt: DbtCliResource): + yield from dbt.cli(["build"], context=context).stream() + + return Definitions(assets=[_fn], resources={"dbt": self.dbt_resource}) diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/defs.yml b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/defs.yml new file mode 100644 index 0000000000000..4ade1fe71c424 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/defs.yml @@ -0,0 +1,5 @@ +component_type: dbt_project + +component_params: + dbt: + project_dir: jaffle_shop \ No newline at end of file diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/.gitignore b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/.gitignore new file mode 100644 index 0000000000000..c12c7f9624ad6 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/.gitignore @@ -0,0 +1,13 @@ + +target/ +dbt_packages/ +dbt_modules/ +logs/ +**/.DS_Store +.user.yml +venv/ +env/ +**/*.duckdb +**/*.duckdb.wal +tmp/ +state/ diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/dbt_project.yml b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/dbt_project.yml new file mode 100644 index 0000000000000..377ac5fae4c90 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/dbt_project.yml @@ -0,0 +1,26 @@ +name: "jaffle_shop" + +config-version: 2 +version: "0.1" + +profile: "jaffle_shop" + +model-paths: ["models"] +seed-paths: ["seeds"] +test-paths: ["tests"] +analysis-paths: ["analysis"] +macro-paths: ["macros"] + +target-path: "target" +clean-targets: + - "target" + - "dbt_modules" + - "logs" + +require-dbt-version: [">=1.0.0", "<2.0.0"] + +models: + jaffle_shop: + materialized: table + staging: + materialized: view diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/customers.sql b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/customers.sql new file mode 100644 index 0000000000000..00fed3033006a --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/customers.sql @@ -0,0 +1,75 @@ +with customers as ( + + select * from {{ ref('stg_customers') }} + +), + +orders as ( + + select * from {{ ref('stg_orders') }} + +), + +payments as ( + + select * from {{ ref('stg_payments') }} + +), + +customer_orders as ( + + select + customer_id, + + min(order_date) as first_order, + max(order_date) as most_recent_order, + count(order_id) as number_of_orders + from orders + + group by customer_id + +), + +customer_payments as ( + + select + orders.customer_id, + sum(amount) as total_amount + + from payments + + left join orders on + payments.order_id = orders.order_id + + group by orders.customer_id + +), + +final as ( + + select + customers.customer_id, + customers.first_name, + customers.last_name, + customer_orders.first_order, + customer_orders.most_recent_order, + customer_orders.number_of_orders, + customer_payments.total_amount as customer_lifetime_value + + from customers + + left join customer_orders + on customers.customer_id = customer_orders.customer_id + + left join customer_payments + on customers.customer_id = customer_payments.customer_id + +) + +select * from final + +{% if var('break_customer_build', 'false') == 'true' %} + +does not work + +{% endif %} diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/docs.md b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/docs.md new file mode 100644 index 0000000000000..d990aad5a92ac --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/docs.md @@ -0,0 +1,13 @@ +{% docs orders_status %} + +Orders can be one of the following statuses: + +| status | description | +| -------------- | ---------------------------------------------------------------------------------------------------------------------- | +| placed | The order has been placed but has not yet left the warehouse | +| shipped | The order has ben shipped to the customer and is currently in transit | +| completed | The order has been received by the customer | +| return_pending | The customer has indicated that they would like to return the order, but it has not yet been received at the warehouse | +| returned | The order has been returned by the customer and received at the warehouse | + +{% enddocs %} diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/orders.sql b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/orders.sql new file mode 100644 index 0000000000000..cbb2934911821 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/orders.sql @@ -0,0 +1,56 @@ +{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %} + +with orders as ( + + select * from {{ ref('stg_orders') }} + +), + +payments as ( + + select * from {{ ref('stg_payments') }} + +), + +order_payments as ( + + select + order_id, + + {% for payment_method in payment_methods -%} + sum(case when payment_method = '{{ payment_method }}' then amount else 0 end) as {{ payment_method }}_amount, + {% endfor -%} + + sum(amount) as total_amount + + from payments + + group by order_id + +), + +final as ( + + select + orders.order_id, + orders.customer_id, + orders.order_date, + orders.status, + + {% for payment_method in payment_methods -%} + + order_payments.{{ payment_method }}_amount, + + {% endfor -%} + + order_payments.total_amount as amount + + from orders + + + left join order_payments + on orders.order_id = order_payments.order_id + +) + +select * from final diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/overview.md b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/overview.md new file mode 100644 index 0000000000000..0544c42b17d5e --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/overview.md @@ -0,0 +1,11 @@ +{% docs __overview__ %} + +## Data Documentation for Jaffle Shop + +`jaffle_shop` is a fictional ecommerce store. + +This [dbt](https://www.getdbt.com/) project is for testing out code. + +The source code can be found [here](https://github.com/clrcrl/jaffle_shop). + +{% enddocs %} diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/schema.yml b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/schema.yml new file mode 100644 index 0000000000000..05c5be6930f7f --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/schema.yml @@ -0,0 +1,83 @@ +version: 2 + +models: + - name: customers + description: This table has basic information about a customer, as well as some derived facts based on a customer's orders + + columns: + - name: customer_id + description: This is a unique identifier for a customer + tests: + - unique + - not_null + + - name: first_name + description: Customer's first name. PII. + + - name: last_name + description: Customer's last name. PII. + + - name: first_order + description: Date (UTC) of a customer's first order + + - name: most_recent_order + description: Date (UTC) of a customer's most recent order + + - name: number_of_orders + description: Count of the number of orders a customer has placed + + - name: total_order_amount + description: Total value (AUD) of a customer's orders + + - name: orders + description: This table has basic information about orders, as well as some derived facts based on payments + + columns: + - name: order_id + tests: + - unique + - not_null + description: This is a unique identifier for an order + + - name: customer_id + description: Foreign key to the customers table + tests: + - not_null + - relationships: + to: ref('customers') + field: customer_id + + - name: order_date + description: Date (UTC) that the order was placed + + - name: status + description: '{{ doc("orders_status") }}' + tests: + - accepted_values: + values: + ["placed", "shipped", "completed", "return_pending", "returned"] + + - name: amount + description: Total amount (AUD) of the order + tests: + - not_null + + - name: credit_card_amount + description: Amount of the order (AUD) paid for by credit card + tests: + - not_null + + - name: coupon_amount + description: Amount of the order (AUD) paid for by coupon + tests: + - not_null + + - name: bank_transfer_amount + description: Amount of the order (AUD) paid for by bank transfer + tests: + - not_null + + - name: gift_card_amount + description: Amount of the order (AUD) paid for by gift card + tests: + - not_null diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/schema.yml b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/schema.yml new file mode 100644 index 0000000000000..258345211a9a2 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/schema.yml @@ -0,0 +1,32 @@ +version: 2 + +models: + - name: stg_customers + columns: + - name: customer_id + tests: + - unique + - not_null + + - name: stg_orders + columns: + - name: order_id + tests: + - unique + - not_null + - name: status + tests: + - accepted_values: + values: + ["placed", "shipped", "completed", "return_pending", "returned"] + + - name: stg_payments + columns: + - name: payment_id + tests: + - unique + - not_null + - name: payment_method + tests: + - accepted_values: + values: ["credit_card", "coupon", "bank_transfer", "gift_card"] diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_customers.sql b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_customers.sql new file mode 100644 index 0000000000000..cad047269506e --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_customers.sql @@ -0,0 +1,22 @@ +with source as ( + + {#- + Normally we would select from the table here, but we are using seeds to load + our data in this project + #} + select * from {{ ref('raw_customers') }} + +), + +renamed as ( + + select + id as customer_id, + first_name, + last_name + + from source + +) + +select * from renamed diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_orders.sql b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_orders.sql new file mode 100644 index 0000000000000..a654dcb9474a7 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_orders.sql @@ -0,0 +1,23 @@ +with source as ( + + {#- + Normally we would select from the table here, but we are using seeds to load + our data in this project + #} + select * from {{ ref('raw_orders') }} + +), + +renamed as ( + + select + id as order_id, + user_id as customer_id, + order_date, + status + + from source + +) + +select * from renamed diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_payments.sql b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_payments.sql new file mode 100644 index 0000000000000..700cf7f4f657b --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/models/staging/stg_payments.sql @@ -0,0 +1,25 @@ +with source as ( + + {#- + Normally we would select from the table here, but we are using seeds to load + our data in this project + #} + select * from {{ ref('raw_payments') }} + +), + +renamed as ( + + select + id as payment_id, + order_id, + payment_method, + + -- `amount` is currently stored in cents, so we convert it to dollars + amount / 100 as amount + + from source + +) + +select * from renamed diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/profiles.yml b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/profiles.yml new file mode 100644 index 0000000000000..b7349909fcbb1 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/profiles.yml @@ -0,0 +1,23 @@ +jaffle_shop: + target: dev + outputs: + dev: + type: duckdb + path: "{{ env_var('DAGSTER_DBT_PYTEST_XDIST_DUCKDB_DBFILE_PATH', 'target/local.duckdb') }}" + schema: "{{ env_var('DAGSTER_DBT_JAFFLE_SCHEMA', 'dev') }}" + threads: 24 + snowflake: + type: snowflake + account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}" + user: "{{ env_var('SNOWFLAKE_USER') }}" + password: "{{ env_var('SNOWFLAKE_PASSWORD') }}" + client_session_keep_alive: False + database: TESTDB + schema: TESTSCHEMA + bigquery: + type: bigquery + method: service-account + project: "{{ env_var('GCP_PROJECT_ID') }}" + dataset: BIGQUERY_IO_MANAGER_SCHEMA + threads: 4 + keyfile: "{{ env_var('GOOGLE_APPLICATION_CREDENTIALS') }}" diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/.gitkeep b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_customers.csv b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_customers.csv new file mode 100644 index 0000000000000..b3e6747d69a20 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_customers.csv @@ -0,0 +1,101 @@ +id,first_name,last_name +1,Michael,P. +2,Shawn,M. +3,Kathleen,P. +4,Jimmy,C. +5,Katherine,R. +6,Sarah,R. +7,Martin,M. +8,Frank,R. +9,Jennifer,F. +10,Henry,W. +11,Fred,S. +12,Amy,D. +13,Kathleen,M. +14,Steve,F. +15,Teresa,H. +16,Amanda,H. +17,Kimberly,R. +18,Johnny,K. +19,Virginia,F. +20,Anna,A. +21,Willie,H. +22,Sean,H. +23,Mildred,A. +24,David,G. +25,Victor,H. +26,Aaron,R. +27,Benjamin,B. +28,Lisa,W. +29,Benjamin,K. +30,Christina,W. +31,Jane,G. +32,Thomas,O. +33,Katherine,M. +34,Jennifer,S. +35,Sara,T. +36,Harold,O. +37,Shirley,J. +38,Dennis,J. +39,Louise,W. +40,Maria,A. +41,Gloria,C. +42,Diana,S. +43,Kelly,N. +44,Jane,R. +45,Scott,B. +46,Norma,C. +47,Marie,P. +48,Lillian,C. +49,Judy,N. +50,Billy,L. +51,Howard,R. +52,Laura,F. +53,Anne,B. +54,Rose,M. +55,Nicholas,R. +56,Joshua,K. +57,Paul,W. +58,Kathryn,K. +59,Adam,A. +60,Norma,W. +61,Timothy,R. +62,Elizabeth,P. +63,Edward,G. +64,David,C. +65,Brenda,W. +66,Adam,W. +67,Michael,H. +68,Jesse,E. +69,Janet,P. +70,Helen,F. +71,Gerald,C. +72,Kathryn,O. +73,Alan,B. +74,Harry,A. +75,Andrea,H. +76,Barbara,W. +77,Anne,W. +78,Harry,H. +79,Jack,R. +80,Phillip,H. +81,Shirley,H. +82,Arthur,D. +83,Virginia,R. +84,Christina,R. +85,Theresa,M. +86,Jason,C. +87,Phillip,B. +88,Adam,T. +89,Margaret,J. +90,Paul,P. +91,Todd,W. +92,Willie,O. +93,Frances,R. +94,Gregory,H. +95,Lisa,P. +96,Jacqueline,A. +97,Shirley,D. +98,Nicole,M. +99,Mary,G. +100,Jean,M. diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_orders.csv b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_orders.csv new file mode 100644 index 0000000000000..7c2be078882c5 --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_orders.csv @@ -0,0 +1,100 @@ +id,user_id,order_date,status +1,1,2018-01-01,returned +2,3,2018-01-02,completed +3,94,2018-01-04,completed +4,50,2018-01-05,completed +5,64,2018-01-05,completed +6,54,2018-01-07,completed +7,88,2018-01-09,completed +8,2,2018-01-11,returned +9,53,2018-01-12,completed +10,7,2018-01-14,completed +11,99,2018-01-14,completed +12,59,2018-01-15,completed +13,84,2018-01-17,completed +14,40,2018-01-17,returned +15,25,2018-01-17,completed +16,39,2018-01-18,completed +17,71,2018-01-18,completed +18,64,2018-01-20,returned +19,54,2018-01-22,completed +20,20,2018-01-23,completed +21,71,2018-01-23,completed +22,86,2018-01-24,completed +23,22,2018-01-26,return_pending +24,3,2018-01-27,completed +25,51,2018-01-28,completed +26,32,2018-01-28,completed +27,94,2018-01-29,completed +28,8,2018-01-29,completed +29,57,2018-01-31,completed +30,69,2018-02-02,completed +31,16,2018-02-02,completed +32,28,2018-02-04,completed +33,42,2018-02-04,completed +34,38,2018-02-06,completed +35,80,2018-02-08,completed +36,85,2018-02-10,completed +37,1,2018-02-10,completed +38,51,2018-02-10,completed +39,26,2018-02-11,completed +40,33,2018-02-13,completed +41,99,2018-02-14,completed +42,92,2018-02-16,completed +43,31,2018-02-17,completed +44,66,2018-02-17,completed +45,22,2018-02-17,completed +46,6,2018-02-19,completed +47,50,2018-02-20,completed +48,27,2018-02-21,completed +49,35,2018-02-21,completed +50,51,2018-02-23,completed +51,71,2018-02-24,completed +52,54,2018-02-25,return_pending +53,34,2018-02-26,completed +54,54,2018-02-26,completed +55,18,2018-02-27,completed +56,79,2018-02-28,completed +57,93,2018-03-01,completed +58,22,2018-03-01,completed +59,30,2018-03-02,completed +60,12,2018-03-03,completed +61,63,2018-03-03,completed +62,57,2018-03-05,completed +63,70,2018-03-06,completed +64,13,2018-03-07,completed +65,26,2018-03-08,completed +66,36,2018-03-10,completed +67,79,2018-03-11,completed +68,53,2018-03-11,completed +69,3,2018-03-11,completed +70,8,2018-03-12,completed +71,42,2018-03-12,shipped +72,30,2018-03-14,shipped +73,19,2018-03-16,completed +74,9,2018-03-17,shipped +75,69,2018-03-18,completed +76,25,2018-03-20,completed +77,35,2018-03-21,shipped +78,90,2018-03-23,shipped +79,52,2018-03-23,shipped +80,11,2018-03-23,shipped +81,76,2018-03-23,shipped +82,46,2018-03-24,shipped +83,54,2018-03-24,shipped +84,70,2018-03-26,placed +85,47,2018-03-26,shipped +86,68,2018-03-26,placed +87,46,2018-03-27,placed +88,91,2018-03-27,shipped +89,21,2018-03-28,placed +90,66,2018-03-30,shipped +91,47,2018-03-31,placed +92,84,2018-04-02,placed +93,66,2018-04-03,placed +94,63,2018-04-03,placed +95,27,2018-04-04,placed +96,90,2018-04-06,placed +97,89,2018-04-07,placed +98,41,2018-04-07,placed +99,85,2018-04-09,placed diff --git a/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_payments.csv b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_payments.csv new file mode 100644 index 0000000000000..a587baab5955d --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/stub_code_locations/dbt_project_location/components/jaffle_shop_dbt/jaffle_shop/seeds/raw_payments.csv @@ -0,0 +1,114 @@ +id,order_id,payment_method,amount +1,1,credit_card,1000 +2,2,credit_card,2000 +3,3,coupon,100 +4,4,coupon,2500 +5,5,bank_transfer,1700 +6,6,credit_card,600 +7,7,credit_card,1600 +8,8,credit_card,2300 +9,9,gift_card,2300 +10,9,bank_transfer,0 +11,10,bank_transfer,2600 +12,11,credit_card,2700 +13,12,credit_card,100 +14,13,credit_card,500 +15,13,bank_transfer,1400 +16,14,bank_transfer,300 +17,15,coupon,2200 +18,16,credit_card,1000 +19,17,bank_transfer,200 +20,18,credit_card,500 +21,18,credit_card,800 +22,19,gift_card,600 +23,20,bank_transfer,1500 +24,21,credit_card,1200 +25,22,bank_transfer,800 +26,23,gift_card,2300 +27,24,coupon,2600 +28,25,bank_transfer,2000 +29,25,credit_card,2200 +30,25,coupon,1600 +31,26,credit_card,3000 +32,27,credit_card,2300 +33,28,bank_transfer,1900 +34,29,bank_transfer,1200 +35,30,credit_card,1300 +36,31,credit_card,1200 +37,32,credit_card,300 +38,33,credit_card,2200 +39,34,bank_transfer,1500 +40,35,credit_card,2900 +41,36,bank_transfer,900 +42,37,credit_card,2300 +43,38,credit_card,1500 +44,39,bank_transfer,800 +45,40,credit_card,1400 +46,41,credit_card,1700 +47,42,coupon,1700 +48,43,gift_card,1800 +49,44,gift_card,1100 +50,45,bank_transfer,500 +51,46,bank_transfer,800 +52,47,credit_card,2200 +53,48,bank_transfer,300 +54,49,credit_card,600 +55,49,credit_card,900 +56,50,credit_card,2600 +57,51,credit_card,2900 +58,51,credit_card,100 +59,52,bank_transfer,1500 +60,53,credit_card,300 +61,54,credit_card,1800 +62,54,bank_transfer,1100 +63,55,credit_card,2900 +64,56,credit_card,400 +65,57,bank_transfer,200 +66,58,coupon,1800 +67,58,gift_card,600 +68,59,gift_card,2800 +69,60,credit_card,400 +70,61,bank_transfer,1600 +71,62,gift_card,1400 +72,63,credit_card,2900 +73,64,bank_transfer,2600 +74,65,credit_card,0 +75,66,credit_card,2800 +76,67,bank_transfer,400 +77,67,credit_card,1900 +78,68,credit_card,1600 +79,69,credit_card,1900 +80,70,credit_card,2600 +81,71,credit_card,500 +82,72,credit_card,2900 +83,73,bank_transfer,300 +84,74,credit_card,3000 +85,75,credit_card,1900 +86,76,coupon,200 +87,77,credit_card,0 +88,77,bank_transfer,1900 +89,78,bank_transfer,2600 +90,79,credit_card,1800 +91,79,credit_card,900 +92,80,gift_card,300 +93,81,coupon,200 +94,82,credit_card,800 +95,83,credit_card,100 +96,84,bank_transfer,2500 +97,85,bank_transfer,1700 +98,86,coupon,2300 +99,87,gift_card,3000 +100,87,credit_card,2600 +101,88,credit_card,2900 +102,89,bank_transfer,2200 +103,90,bank_transfer,200 +104,91,credit_card,1900 +105,92,bank_transfer,1500 +106,92,coupon,200 +107,93,gift_card,2600 +108,94,coupon,700 +109,95,coupon,2400 +110,96,gift_card,1700 +111,97,bank_transfer,1400 +112,98,bank_transfer,1000 +113,99,credit_card,2400 diff --git a/examples/experimental/dagster-components/dagster_components_tests/test_dbt_project.py b/examples/experimental/dagster-components/dagster_components_tests/test_dbt_project.py new file mode 100644 index 0000000000000..0d35354a2a0ea --- /dev/null +++ b/examples/experimental/dagster-components/dagster_components_tests/test_dbt_project.py @@ -0,0 +1,75 @@ +import shutil +import tempfile +from contextlib import contextmanager +from pathlib import Path +from typing import Generator + +import pytest +from dagster import AssetKey +from dagster_components.core.component_decl_builder import DefsFileModel +from dagster_components.core.component_defs_builder import ( + YamlComponentDecl, + build_components_from_component_folder, + defs_from_components, +) +from dagster_components.impls.dbt_project import DbtProjectComponent +from dagster_dbt import DbtProject + +from dagster_components_tests.utils import assert_assets, get_asset_keys, script_load_context + +STUB_LOCATION_PATH = Path(__file__).parent / "stub_code_locations" / "dbt_project_location" +COMPONENT_RELPATH = "components/jaffle_shop_dbt" + +JAFFLE_SHOP_KEYS = { + AssetKey("customers"), + AssetKey("orders"), + AssetKey("raw_customers"), + AssetKey("raw_orders"), + AssetKey("raw_payments"), + AssetKey("stg_customers"), + AssetKey("stg_orders"), + AssetKey("stg_payments"), +} + + +@contextmanager +@pytest.fixture(scope="module") +def dbt_path() -> Generator[Path, None, None]: + with tempfile.TemporaryDirectory() as temp_dir: + shutil.copytree(STUB_LOCATION_PATH, temp_dir, dirs_exist_ok=True) + # make sure a manifest.json file is created + project = DbtProject(Path(temp_dir) / "components/jaffle_shop_dbt/jaffle_shop") + project.preparer.prepare(project) + yield Path(temp_dir) + + +def test_python_params(dbt_path: Path) -> None: + component = DbtProjectComponent.from_decl_node( + context=script_load_context(), + decl_node=YamlComponentDecl( + path=dbt_path / COMPONENT_RELPATH, + defs_file_model=DefsFileModel( + component_type="dbt_project", + component_params={"dbt": {"project_dir": "jaffle_shop"}}, + ), + ), + ) + assert get_asset_keys(component) == JAFFLE_SHOP_KEYS + + +def test_load_from_path(dbt_path: Path) -> None: + components = build_components_from_component_folder( + script_load_context(), dbt_path / "components" + ) + assert len(components) == 1 + assert get_asset_keys(components[0]) == JAFFLE_SHOP_KEYS + + assert_assets(components[0], len(JAFFLE_SHOP_KEYS)) + + defs = defs_from_components( + context=script_load_context(), + components=components, + resources={}, + ) + + assert defs.get_asset_graph().get_all_asset_keys() == JAFFLE_SHOP_KEYS diff --git a/examples/experimental/dagster-components/dagster_components_tests/utils.py b/examples/experimental/dagster-components/dagster_components_tests/utils.py index e381616a1fb70..a6655490e423e 100644 --- a/examples/experimental/dagster-components/dagster_components_tests/utils.py +++ b/examples/experimental/dagster-components/dagster_components_tests/utils.py @@ -1,18 +1,10 @@ from dagster import AssetKey, DagsterInstance +from dagster_components import __component_registry__ from dagster_components.core.component import Component, ComponentLoadContext, ComponentRegistry -from dagster_components.impls.pipes_subprocess_script_collection import ( - PipesSubprocessScriptCollection, -) -from dagster_components.impls.sling_replication import SlingReplicationComponent def registry() -> ComponentRegistry: - return ComponentRegistry( - { - "sling_replication": SlingReplicationComponent, - "pipes_subprocess_script_collection": PipesSubprocessScriptCollection, - } - ) + return ComponentRegistry(__component_registry__) def script_load_context() -> ComponentLoadContext: diff --git a/examples/experimental/dagster-components/setup.py b/examples/experimental/dagster-components/setup.py index cdd2588a083e2..d614b2d5904b2 100644 --- a/examples/experimental/dagster-components/setup.py +++ b/examples/experimental/dagster-components/setup.py @@ -46,5 +46,6 @@ def get_version() -> str: }, extras_require={ "sling": ["dagster-embedded-elt"], + "dbt": ["dagster-dbt"], }, ) diff --git a/examples/experimental/dagster-components/tox.ini b/examples/experimental/dagster-components/tox.ini index f4c307393b1a3..f3d40eea7d3ac 100644 --- a/examples/experimental/dagster-components/tox.ini +++ b/examples/experimental/dagster-components/tox.ini @@ -13,6 +13,7 @@ deps = -e ../../../python_modules/dagster-test -e ../../../python_modules/dagster-pipes -e ../../../python_modules/libraries/dagster-embedded-elt + -e ../../../python_modules/libraries/dagster-dbt -e . allowlist_externals = /bin/bash