0% found this document useful (0 votes)
104 views5 pages

Snowpark Data Engineering Overview

This document demonstrates connecting to Snowflake via Snowpark without using PySpark. It shows how to join and aggregate large tables, write results to a new table, and scale the warehouse size. Key benefits of Snowpark over Spark/PySpark are also summarized, including being quicker to migrate to, cheaper by using serverless compute that scales instantly, faster by eliminating unnecessary data movement, and easier to use with less maintenance required.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
104 views5 pages

Snowpark Data Engineering Overview

This document demonstrates connecting to Snowflake via Snowpark without using PySpark. It shows how to join and aggregate large tables, write results to a new table, and scale the warehouse size. Key benefits of Snowpark over Spark/PySpark are also summarized, including being quicker to migrate to, cheaper by using serverless compute that scales instantly, faster by eliminating unnecessary data movement, and easier to use with less maintenance required.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
  • Connect to Snowflake via SnowPark
  • Install Snowpark
  • Start Data Engineering Process
  • Storing the Results
  • Scale Down Compute
  • Benefits of Snowpark Over Spark & PySpark

[Link]

com/NickAkincilar/Sample_Snowpark_Demos/blob/main/
Snowpark_Data_Engineering_Public.ipynb

[Link]
the-snowflake-data-marketplace-and-deploy-in-database/

Install Snowpark
In [ ]:
# !pip install snowflake-snowpark-python

Connect to Snowflake via SnowPark (&


without PySpark)
In [32]:
import time
# ---> REMOVE PYSPARK REFERENCES

# import [Link] as f
# from [Link] import SparkSession
# from [Link] import udf,col
# from [Link] import IntegerType
# spark = [Link]("DataEngeering1").getOrCreate()

# <--- REPLACE WITH SNOWPARK REFERENCES (Rest of code is almost


identical)

import [Link] as f
from [Link] import Session, DataFrame
from [Link] import udf, col
from [Link] import IntegerType
from [Link] import call_udf

# <----- Make these changes before running the notebook -------


# Change Connection params to match your environment
#
<------------------------------------------------------------------------
----

Warehouse_Name = 'MY_DEMO_WH'
Warehouse_Size = "LARGE"
DB_name = 'DEMO_SNOWPARK'
Schema_Name = 'Public'

CONNECTION_PARAMETERS= {
'account': '<Snowflake_Account_Locator>',
'user': 'SomeUser',
'password': 'Not4u2Know',
'role': 'SYSADMIN'
}

print("Connecting to Snowflake.....\n")
session = [Link](CONNECTION_PARAMETERS).create()
print("Connected Successfully!...\n")

sql_cmd = f"CREATE OR REPLACE WAREHOUSE {Warehouse_Name} WAREHOUSE_SIZE =


'X-Small' AUTO_SUSPEND = 10 "
print("XS Cluster Created & Ready \n")

[Link](sql_cmd).collect()

sql_cmd = f"CREATE OR REPLACE DATABASE {DB_name}"


[Link](sql_cmd).collect()
print("Database is Created & Ready \n")

session.use_database(DB_name)
session.use_schema(Schema_Name)
session.use_warehouse(Warehouse_Name)
Connecting to Snowflake.....

Connected Successfully!...

XS Cluster Created & Ready

Database is Created & Ready

Start Data Engineering Process


In [30]:
# 2 - READ & JOIN 2 LARGE TABLES (600M & 1M rows)
print("Joining, Aggregating with 2 large tables(600M & 1M rows) & Writing
results to new table(80M rows) ..\n")

dfLineItems = [Link]("SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.LINEITEM")
# 600 Million Rows
dfSuppliers = [Link]("SNOWFLAKE_SAMPLE_DATA.TPCH_SF100.SUPPLIER")
# 1 Million Rows

print('Lineitems Table: %s rows' % [Link]())


print('Suppliers Table: %s rows' % [Link]())

# 3 - JOIN TABLES
dfJoinTables = [Link](dfSuppliers,
[Link]("L_SUPPKEY") ==
[Link]("S_SUPPKEY"))

# 4 - SUMMARIZE THE DATA BY SUPPLIER, PART, SUM, MIN & MAX


dfSummary = [Link]("S_NAME", "L_PARTKEY").agg([
[Link]("L_QUANTITY").alias("TOTAL_QTY"),
[Link]("L_QUANTITY").alias("MIN_QTY"),
[Link]("L_QUANTITY").alias("MAX_QTY"),
])
Joining, Aggregating with 2 large tables(600M & 1M rows) & Writing
results to new table(80M rows) ..

Lineitems Table: 600037902 rows


Suppliers Table: 1000000 rows

↑ Compute is NOT used up to this point. (Lazy Execution Model) !!!

3. Storing the Results in Table or Showing results


triggers the compute & previous steps.
In [31]:
start_time = [Link]()

# 4 - INCREASE COMPUTE SIZE


print( f"Resizing to from XS(1 Node) to {Warehouse_Size} ..")

sql_cmd = f"ALTER WAREHOUSE {Warehouse_Name} SET WAREHOUSE_SIZE =


'{Warehouse_Size}' WAIT_FOR_COMPLETION = TRUE"
[Link](sql_cmd).collect()

print("Completed!...\n\n")

# 5 - WRITE THE RESULTS TO A NEW TABLE ( 80 Million Rows)


# <-- This is when all the previous operations are compiled & executed as
a single job
print("Creating the target SALES_SUMMARY table...\n\n")
[Link]("overwrite").saveAsTable("SALES_SUMMARY")
print("Target Table Created!...")

# 6 - QUERY THE RESULTS (80 Million Rows)


print("Querying the results..\n")
dfSales = [Link]("SALES_SUMMARY")
[Link]()
end_time = [Link]()
# 7 - SCALE DOWN COMPUTE TO 1 NODE
print("Reducing the warehouse to XS..\n")
sql_cmd = "ALTER WAREHOUSE {} SET WAREHOUSE_SIZE =
'XSMALL'".format(Warehouse_Name)
[Link](sql_cmd).collect()

print("Completed!...\n")

print("--- %s seconds to Join, Summarize & Write Results to a new Table


--- \n" % int(end_time - start_time))
print("--- %s Rows Written to SALES_SUMMARY table" % [Link]())
Resizing to from XS(1 Node) to LARGE ..
Completed!...

Creating the target SALES_SUMMARY table...

Target Table Created!...


Querying the results..

-------------------------------------------------------------------------
-
|"S_NAME" |"L_PARTKEY" |"TOTAL_QTY" |"MIN_QTY" |"MAX_QTY"
|
-------------------------------------------------------------------------
-
|Supplier#000941845 |13441818 |163.00 |14.00 |45.00
|
|Supplier#000816569 |1316566 |287.00 |3.00 |50.00
|
|Supplier#000305838 |18555783 |219.00 |3.00 |49.00
|
|Supplier#000030491 |10030490 |203.00 |4.00 |47.00
|
|Supplier#000659231 |1409229 |158.00 |19.00 |50.00
|
|Supplier#000911793 |13911792 |310.00 |2.00 |49.00
|
|Supplier#000560166 |9310156 |108.00 |6.00 |44.00
|
|Supplier#000598113 |7598112 |155.00 |12.00 |47.00
|
|Supplier#000951634 |16701617 |190.00 |9.00 |50.00
|
|Supplier#000460895 |7210887 |268.00 |4.00 |49.00
|
-------------------------------------------------------------------------
-
Reducing the warehouse to XS..

Completed!...

--- 19 seconds to Join, Summarize & Write Results to a new Table ---

--- 79975543 Rows Written to SALES_SUMMARY table

Benefits of Snowpark Over Spark &


PySpark
- Quick to Migrate as code is mostly identical & does not require re-learning
new language

- Cheaper as compute is fully serverless. It can Scale (up/Down) instantly via


code & runs(costs) only when in use.

- Faster as all unnecesseary data movement is eliminated = Less time using


Compute = Less Cost

- Easier to use = Less FTE as Little to No Maintanence needed for Compute


& Storage.

[Link]

Common questions

Powered by AI

Snowpark handles large-scale data operations effectively by leveraging its lazy execution model, which defers computation until absolutely necessary. This approach allows users to define operations without immediately triggering compute processes. For example, in a scenario where two large tables (one with 600 million rows and another with 1 million rows) are joined and summarized, Snowpark waits until the complete set of instructions is available before executing. This not only optimizes resource utilization but also aligns with the scalability of Snowpark's serverless architecture, allowing for resizing compute resources on-the-fly to handle large data volumes .

Snowpark offers several advantages over Spark and PySpark, making it a more attractive option for data engineering tasks. It allows for quicker migration as the code is almost identical to existing frameworks, eliminating the need to learn a new programming language. Additionally, Snowpark is cost-effective since it operates on a fully serverless architecture, scaling up and down instantly as needed. This efficiency translates to lower costs with compute resources being used only when necessary. Moreover, Snowpark provides faster data processing by minimizing unnecessary data movement, thereby reducing computation time and cost. Finally, it is easier to maintain, requiring fewer full-time equivalents due to minimal maintenance needs for compute and storage components .

Snowpark's seamless integration with tools like PySpark benefits teams transitioning their workflows by providing a familiar coding environment that reduces the learning curve typically associated with new tools. This compatibility ensures that most existing PySpark code can be quickly adapted to Snowpark, allowing teams to retain their data processing logic with minimal modifications. Furthermore, the identical syntax eases the migration process, enabling teams to leverage Snowpark's advantages, such as improved cost efficiency and resource optimization, without having to re-architect their entire workflow .

The inclusion of Snowpark's Python UDFs enhances Snowflake's functionality by allowing data engineers to create custom data processing logic that can be executed directly within Snowflake. This eliminates the need to transfer data out of Snowflake for processing, reducing latency and enhancing performance. Python UDFs enable the application of complex algorithms and data transformations at scale, leveraging Snowflake's compute capabilities. This integration enriches the analytical power available to data engineers while maintaining the simplicity and efficiency of working within the Snowflake environment .

Snowpark's ability to scale compute resources on-demand significantly impacts the efficiency of processing extensive datasets. During intensive operations like joining, aggregating, or transforming data, adjusting the compute warehouse size ensures that the necessary resources are available for rapid processing. This scalability minimizes downtime and optimizes job completion times, enabling large data operations to proceed smoothly without resource constraints. After completing operations, resources can be scaled down to minimize costs, thus balancing performance demands with financial efficiency .

Snowpark's serverless architecture contributes to cost savings by allowing compute resources to be used only when needed, thereby minimizing idle time and associated costs. It achieves this flexibility through the ability to instantly scale compute instances up or down depending on demand. For data processing tasks, this means that resources are allocated only during the actual execution of jobs, with the possibility of reducing the compute size immediately afterward. This dynamic allocation helps eliminate unnecessary expenses that would normally accrue from continuously running compute resources in traditional data processing methods .

Establishing a connection to Snowflake using Snowpark involves several key steps. First, the connection parameters, such as account locator, user credentials, and role, must be configured to match the user environment. Once these details are set, a session is created using the Snowpark API's Session.builder.configs method. After the connection is established successfully, users can interact with Snowflake to perform various data engineering tasks. The smooth data engineering process is facilitated by Snowpark's capacity to manage session states and handle subsequent data operations, such as creating and utilizing databases, schemas, and warehouses configured within the session .

Snowpark uses several operational strategies to efficiently manage large data volumes. Key among these is the lazy execution model, which postpones computation and optimizes resource use by entering into compute processes only when absolutely required. This approach negates unnecessary intermediate storage operations and streamlines data handling. Additionally, the ability to scale compute resources dynamically allows Snowpark to handle extensive datasets by provisioning proper resource scaling, executed just at the time of need. These strategies collectively result in optimized processing time, reduced operational costs, and the seamless handling of complex data engineering tasks .

Snowpark's lazy execution model optimizes performance and resource utilization by deferring the actual computation until an action that necessitates execution, like writing to a table or retrieving query results, is encountered. This allows users to define multiple operations sequentially without incurring immediate computation costs. The model compiles the entire command set into a single executable job, optimizing resource allocation and reducing overhead caused by fragmentary execution. As a result, tasks like joining and aggregating large datasets can be more efficiently managed with resources precisely tailored to the actual operational load at execution time .

Snowpark ensures effective use of compute resources through a combination of its lazy execution model and ability to dynamically resize compute resources. During large-scale data operations, such as joining and summarizing large tables, the instructions are collected without immediate execution. Once all operations are defined, Snowpark compiles them into a single job to be executed. Before execution, users can resize compute resources to match requirements, such as increasing from a single node instance to a larger configuration. This allows all necessary computations to occur at the optimized resource level, with the option to scale down immediately after task completion, ensuring compute resources are used efficiently .

https://github.com/NickAkincilar/Sample_Snowpark_Demos/blob/main/ (https://github.com/NickAkincilar/Sample_Snowpark_Demos/blo
Warehouse_Size = "LARGE"
DB_name = 'DEMO_SNOWPARK'
Schema_Name = 'Public'
CONNECTION_PARAMETERS= {
    'account': '<Snowflake
print('Suppliers Table: %s rows' % dfSuppliers.count())
# 3 - JOIN TABLES
dfJoinTables = dfLineItems.join(dfSuppliers,
# 7 - SCALE DOWN COMPUTE TO 1 NODE
print("Reducing the warehouse to XS..
")
sql_cmd = "ALTER WAREHOUSE {} SET WAREHOUSE_SIZE
Reducing the warehouse to XS..
Completed!...
--- 19 seconds to Join, Summarize & Write Results to a new Table --- 
--- 799755

You might also like