Ctrl K
ComunidadGuías…

examples/snowflake_target/main.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Write a small set of order rows to Snowflake with a CocoIndex table target."""

from __future__ import annotations

import os
from collections.abc import Iterator
from dataclasses import dataclass

from dotenv import load_dotenv

import cocoindex as coco
from cocoindex.connectors import snowflake

load_dotenv()

SNOWFLAKE = coco.ContextKey[snowflake.ConnectionConfig]("snowflake_demo")

DATABASE = os.environ.get("SNOWFLAKE_DATABASE", "COCOINDEX_DEMO_DB")
SCHEMA = os.environ.get("SNOWFLAKE_SCHEMA", "PUBLIC")
TABLE_NAME = os.environ.get("SNOWFLAKE_TABLE", "COCOINDEX_ORDERS")


@dataclass(frozen=True)
class SourceOrder:
    order_id: str
    customer: str
    product: str
    quantity: int
    unit_price: float
    status: str
    attributes: dict[str, object]


@dataclass(frozen=True)
class SnowflakeOrder:
    order_id: str
    customer: str
    product: str
    quantity: int
    unit_price: float
    order_total: float
    status: str
    attributes: dict[str, object]


SAMPLE_ORDERS = (
    SourceOrder(
        order_id="ORD-1001",
        customer="Summit Labs",
        product="mechanical keyboard",
        quantity=2,
        unit_price=129.50,
        status="paid",
        attributes={"channel": "web", "priority": "standard"},
    ),
    SourceOrder(
        order_id="ORD-1002",
        customer="Beacon Retail",
        product="standing desk",
        quantity=1,
        unit_price=399.00,
        status="paid",
        attributes={"channel": "sales", "priority": "rush"},
    ),
    SourceOrder(
        order_id="ORD-1003",
        customer="Ridgeview Health",
        product="noise cancelling headphones",
        quantity=3,
        unit_price=199.99,
        status="pending",
        attributes={"channel": "partner", "priority": "expedite"},
    ),
)


@coco.lifespan
def coco_lifespan(builder: coco.EnvironmentBuilder) -> Iterator[None]:
    builder.provide(
        SNOWFLAKE,
        snowflake.ConnectionConfig(
            account=os.environ["SNOWFLAKE_ACCOUNT"],
            user=os.environ["SNOWFLAKE_USER"],
            password=os.environ["SNOWFLAKE_PASSWORD"],
            warehouse=os.environ.get("SNOWFLAKE_WAREHOUSE"),
            role=os.environ.get("SNOWFLAKE_ROLE") or None,
        ),
    )
    yield


@coco.fn(memo=True)
async def process_order(
    order: SourceOrder,
    table: snowflake.TableTarget[SnowflakeOrder],
) -> None:
    table.declare_row(
        row=SnowflakeOrder(
            order_id=order.order_id,
            customer=order.customer,
            product=order.product,
            quantity=order.quantity,
            unit_price=order.unit_price,
            order_total=round(order.quantity * order.unit_price, 2),
            status=order.status,
            attributes=order.attributes,
        )
    )


@coco.fn
async def app_main() -> None:
    table = await snowflake.mount_table_target(
        SNOWFLAKE,
        table_name=TABLE_NAME,
        table_schema=await snowflake.TableSchema.from_class(
            SnowflakeOrder,
            primary_key=["order_id"],
        ),
        database=DATABASE,
        schema=SCHEMA,
    )

    await coco.mount_each(
        process_order,
        ((order.order_id, order) for order in SAMPLE_ORDERS),
        table,
    )


app = coco.App(
    coco.AppConfig(name="SnowflakeTarget"),
    app_main,
)


def _qualified_table_name() -> str:
    return f'"{DATABASE}"."{SCHEMA}"."{TABLE_NAME}"'


def print_rows() -> None:
    import snowflake.connector

    conn = snowflake.connector.connect(
        account=os.environ["SNOWFLAKE_ACCOUNT"],
        user=os.environ["SNOWFLAKE_USER"],
        password=os.environ["SNOWFLAKE_PASSWORD"],
        warehouse=os.environ.get("SNOWFLAKE_WAREHOUSE"),
        role=os.environ.get("SNOWFLAKE_ROLE") or None,
    )
    try:
        cursor = conn.cursor()
        try:
            cursor.execute(
                f"""
                SELECT
                    "order_id",
                    "customer",
                    "product",
                    "quantity",
                    "order_total",
                    "status",
                    "attributes":channel::string AS channel
                FROM {_qualified_table_name()}
                ORDER BY "order_id"
                """
            )
            for row in cursor.fetchall():
                print(row)
        finally:
            cursor.close()
    finally:
        conn.close()


if __name__ == "__main__":
    print_rows()