Verwenden von DataFrames in Snowpark Python¶
In Snowpark erfolgt die Abfrage und Verarbeitung von Daten hauptsächlich über einen DataFrame. Unter diesem Thema wird erklärt, wie Sie DataFrames verwenden.
Unter diesem Thema:
Verwenden Sie zum Abrufen und Ändern von Daten die Klasse DataFrame
. Ein DataFrame repräsentiert ein relationales Dataset, das im Lazy-Modus ausgewertet wird: Es wird nur ausgeführt, wenn eine bestimmte Aktion ausgelöst wird. In gewissem Sinne ist ein DataFrame wie eine Abfrage, die ausgewertet werden muss, um Daten abzurufen.
So rufen Sie Daten in einem DataFrame ab:
Konstruieren Sie ein DataFrame, das die Datenquelle für das Dataset angibt.
Sie können z. B. einen DataFrame erstellen, der Daten aus einer Tabelle, Daten einer externen CSV-Datei oder die Ausführung einer SQL-Anweisung enthält.
Geben Sie an, wie das Dataset in den DataFrame transformiert werden soll.
Sie können z. B. angeben, welche Spalten ausgewählt werden sollen, wie die Zeilen gefiltert werden sollen, wie die Ergebnisse sortiert und gruppiert werden sollen usw.
Führen Sie die Anweisung aus, um die Daten in den DataFrame abzurufen.
Um die Daten in den DataFrame abzurufen, müssen Sie eine Methode aufrufen, die eine Aktion ausführt (z. B. die
collect()
-Methode).
In den nächsten Abschnitten werden diese Schritte näher erläutert.
Einrichten der Beispiele für diesen Abschnitt¶
Einige der Beispiele in diesem Abschnitt verwenden einen DataFrame, um eine Tabelle namens sample_product_data
abzufragen. Wenn Sie diese Beispiele ausführen möchten, können Sie diese Tabelle erstellen und mit einigen Daten füllen, indem Sie die folgenden SQL-Anweisungen ausführen:
Sie können die SQL-Anweisungen mit Snowpark Python ausführen:
>>> session.sql('CREATE OR REPLACE TABLE sample_product_data (id INT, parent_id INT, category_id INT, name VARCHAR, serial_number VARCHAR, key INT, "3rd" INT)').collect()
[Row(status='Table SAMPLE_PRODUCT_DATA successfully created.')]
>>> session.sql("""
... INSERT INTO sample_product_data VALUES
... (1, 0, 5, 'Product 1', 'prod-1', 1, 10),
... (2, 1, 5, 'Product 1A', 'prod-1-A', 1, 20),
... (3, 1, 5, 'Product 1B', 'prod-1-B', 1, 30),
... (4, 0, 10, 'Product 2', 'prod-2', 2, 40),
... (5, 4, 10, 'Product 2A', 'prod-2-A', 2, 50),
... (6, 4, 10, 'Product 2B', 'prod-2-B', 2, 60),
... (7, 0, 20, 'Product 3', 'prod-3', 3, 70),
... (8, 7, 20, 'Product 3A', 'prod-3-A', 3, 80),
... (9, 7, 20, 'Product 3B', 'prod-3-B', 3, 90),
... (10, 0, 50, 'Product 4', 'prod-4', 4, 100),
... (11, 10, 50, 'Product 4A', 'prod-4-A', 4, 100),
... (12, 10, 50, 'Product 4B', 'prod-4-B', 4, 100)
... """).collect()
[Row(number of rows inserted=12)]
Um zu überprüfen, ob die Tabelle erstellt wurde, führen Sie folgende Anweisung aus:
>>> session.sql("SELECT count(*) FROM sample_product_data").collect()
[Row(COUNT(*)=12)]
Einrichten der Beispiele in einem Python-Arbeitsblatt¶
Um diese Beispiele in einem Python-Arbeitsblatt einzurichten und auszuführen, erstellen Sie die Beispieltabelle und richten Sie Ihr Python-Arbeitsblatt ein.
Erstellen Sie ein SQL-Arbeitsblatt, und führen Sie Folgendes aus:
CREATE OR REPLACE TABLE sample_product_data (id INT, parent_id INT, category_id INT, name VARCHAR, serial_number VARCHAR, key INT, "3rd" INT); INSERT INTO sample_product_data VALUES (1, 0, 5, 'Product 1', 'prod-1', 1, 10), (2, 1, 5, 'Product 1A', 'prod-1-A', 1, 20), (3, 1, 5, 'Product 1B', 'prod-1-B', 1, 30), (4, 0, 10, 'Product 2', 'prod-2', 2, 40), (5, 4, 10, 'Product 2A', 'prod-2-A', 2, 50), (6, 4, 10, 'Product 2B', 'prod-2-B', 2, 60), (7, 0, 20, 'Product 3', 'prod-3', 3, 70), (8, 7, 20, 'Product 3A', 'prod-3-A', 3, 80), (9, 7, 20, 'Product 3B', 'prod-3-B', 3, 90), (10, 0, 50, 'Product 4', 'prod-4', 4, 100), (11, 10, 50, 'Product 4A', 'prod-4-A', 4, 100), (12, 10, 50, 'Product 4B', 'prod-4-B', 4, 100); SELECT count(*) FROM sample_product_data;
Erstellen Sie ein Python-Arbeitsblatt, und legen Sie denselben Datenbank- und Schemakontext fest wie beim SQL-Arbeitsblatt, das Sie zum Erstellen der Tabelle
sample_product_data
verwendet haben.
Wenn Sie die Beispiele unter diesem Thema in einem Python-Arbeitsblatt verwenden möchten, verwenden Sie das Beispiel innerhalb der Handler-Funktion (z. B. main
), und verwenden Sie das Session
-Objekt, das an die Funktion übergeben wird, um DataFrameszu erstellen.
Rufen Sie beispielsweise die Methode table
des Objekts session
auf, um einen DataFrame für eine Tabelle zu erstellen:
import snowflake.snowpark as snowpark
from snowflake.snowpark.functions import col
def main(session: snowpark.Session):
df_table = session.table("sample_product_data")
Verwenden Sie die Registerkarte Output, um die von der Funktion generierte Ausgabe zu überprüfen, z. B. durch Aufrufen der show
-Methode des DataFrame-Objekts.
Um den von der Funktion zurückgegebenen Wert zu untersuchen, wählen Sie den Datentyp des Rückgabewerts unter Settings » Return type aus, und verwenden Sie die Registerkarte Results wie folgt:
Wenn Ihre Funktion einen DataFrame zurückgibt, verwenden Sie den Standard-Rückgabetyp Table.
Wenn Ihre Funktion eine Liste (
list
) von Zeilen (Row
) von dercollect
-Methode eines DataFrame-Objekts zurückgibt, verwenden Sie Variant als Rückgabetyp.Wenn Ihre Funktion einen beliebigen anderen Wert zurückgibt, der in eine Zeichenfolge umgewandelt werden kann, oder wenn Ihre Funktion keinen Wert zurückgibt, verwenden Sie String als Rückgabetyp.
Weitere Informationen dazu finden Sie unter Ausführen von Python-Arbeitsblättern.
Erstellen eines DataFrame¶
Um einen DataFrame zu erstellen, können Sie die Methoden und Eigenschaften der Session
-Klasse verwenden. Jede der folgenden Methoden erstellt einen DataFrame aus einem anderen Typ von Datenquelle:
Sie können diese Beispiele in Ihrer lokalen Entwicklungsumgebung ausführen oder sie innerhalb der main
-Funktion aufrufen, die in einem Python-Arbeitsblatt definiert ist.
Um einen DataFrame aus Daten einer Tabelle, einer Ansicht oder eines Streams zu erstellen, rufen Sie die
table
-Methode auf:>>> # Create a DataFrame from the data in the "sample_product_data" table. >>> df_table = session.table("sample_product_data") # To print out the first 10 rows, call df_table.show()
Um einen DataFrame aus angegebenen Werten zu erstellen, rufen Sie die
create_dataframe
-Methode auf:>>> # Create a DataFrame with one column named a from specified values. >>> df1 = session.create_dataframe([1, 2, 3, 4]).to_df("a") >>> df1.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df1 ------- |"A" | ------- |1 | |2 | |3 | |4 | -------
Erstellen Sie einen DataFrame mit den vier Spalten „a“, „b“, „c“ und „d“:
>>> # Create a DataFrame with 4 columns, "a", "b", "c" and "d". >>> df2 = session.create_dataframe([[1, 2, 3, 4]], schema=["a", "b", "c", "d"]) >>> df2.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df2 ------------------------- |"A" |"B" |"C" |"D" | ------------------------- |1 |2 |3 |4 | -------------------------
Erstellen Sie einen weiteren DataFrame mit den vier Spalten „a“, „b“, „c“ und „d“:
>>> # Create another DataFrame with 4 columns, "a", "b", "c" and "d". >>> from snowflake.snowpark import Row >>> df3 = session.create_dataframe([Row(a=1, b=2, c=3, d=4)]) >>> df3.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df3 ------------------------- |"A" |"B" |"C" |"D" | ------------------------- |1 |2 |3 |4 | -------------------------
Erstellen Sie einen DataFrame, und geben Sie ein Schema an:
>>> # Create a DataFrame and specify a schema >>> from snowflake.snowpark.types import IntegerType, StringType, StructType, StructField >>> schema = StructType([StructField("a", IntegerType()), StructField("b", StringType())]) >>> df4 = session.create_dataframe([[1, "snow"], [3, "flake"]], schema) >>> df4.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df4 --------------- |"A" |"B" | --------------- |1 |snow | |3 |flake | ---------------
Um einen DataFrame zu erstellen, der einen Wertebereich enthält, rufen Sie die
range
-Methode auf:>>> # Create a DataFrame from a range >>> # The DataFrame contains rows with values 1, 3, 5, 7, and 9 respectively. >>> df_range = session.range(1, 10, 2).to_df("a") >>> df_range.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_range ------- |"A" | ------- |1 | |3 | |5 | |7 | |9 | -------
Um einen DataFrame zu erstellen, der die Daten aus einer in einem Stagingbereich befindlichen Datei enthält, verwenden Sie die Eigenschaft
read
zum Abrufen einesDataFrameReader
-Objekts. ImDataFrameReader
-Objekt rufen Sie die Methode auf, die dem Format der Daten in der Datei entspricht:>>> from snowflake.snowpark.types import StructType, StructField, StringType, IntegerType >>> # Create DataFrames from data in a stage. >>> df_json = session.read.json("@my_stage2/data1.json") >>> df_catalog = session.read.schema(StructType([StructField("name", StringType()), StructField("age", IntegerType())])).csv("@stage/some_dir")
Um einen DataFrame zu erstellen, der die Ergebnisse einer SQL-Abfrage enthält, rufen Sie die
sql
-Methode auf:>>> # Create a DataFrame from a SQL query >>> df_sql = session.sql("SELECT name from sample_product_data") >>> df_sql.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_sql -------------- |"NAME" | -------------- |Product 1 | |Product 1A | |Product 1B | |Product 2 | |Product 2A | |Product 2B | |Product 3 | |Product 3A | |Product 3B | |Product 4 | --------------
Auch wenn es mit der
sql
-Methode möglich ist, durch Ausführen von SELECT-Anweisungen Daten aus Tabellen und Stagingdateien abzurufen, bietet die Verwendung der Methodetable
und der Eigenschaftread
eine bessere Syntax- und Fehlerhervorhebung sowie intelligente Codevervollständigung in Entwicklungstools.
Festlegen der Transformation des Datasets¶
Um anzugeben, welche Spalten ausgewählt und wie die Ergebnisse gefiltert, sortiert, gruppiert usw. werden sollen, rufen Sie die DataFrame-Methoden auf, die das Dataset transformieren. Um die Spalten in diesen Methoden zu identifizieren, verwenden Sie die Funktion col
oder einen Ausdruck, der eine Spalte ergibt Weitere Informationen dazu finden Sie unter Angeben von Spalten und Ausdrücken.
Beispiel:
Zur Angabe der Zeilen, die zurückgegeben werden sollen, rufen Sie die
filter
-Methode auf:>>> # Import the col function from the functions module. >>> # Python worksheets import this function by default >>> from snowflake.snowpark.functions import col >>> # Create a DataFrame for the rows with the ID 1 >>> # in the "sample_product_data" table. >>> # This example uses the == operator of the Column object to perform an >>> # equality check. >>> df = session.table("sample_product_data").filter(col("id") == 1) >>> df.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df ------------------------------------------------------------------------------------ |"ID" |"PARENT_ID" |"CATEGORY_ID" |"NAME" |"SERIAL_NUMBER" |"KEY" |"3rd" | ------------------------------------------------------------------------------------ |1 |0 |5 |Product 1 |prod-1 |1 |10 | ------------------------------------------------------------------------------------
Zur Angabe der Spalten, die ausgewählt werden sollen, rufen Sie die
select
-Methode auf:>>> # Import the col function from the functions module. >>> from snowflake.snowpark.functions import col >>> # Create a DataFrame that contains the id, name, and serial_number >>> # columns in the "sample_product_data" table. >>> df = session.table("sample_product_data").select(col("id"), col("name"), col("serial_number")) >>> df.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df --------------------------------------- |"ID" |"NAME" |"SERIAL_NUMBER" | --------------------------------------- |1 |Product 1 |prod-1 | |2 |Product 1A |prod-1-A | |3 |Product 1B |prod-1-B | |4 |Product 2 |prod-2 | |5 |Product 2A |prod-2-A | |6 |Product 2B |prod-2-B | |7 |Product 3 |prod-3 | |8 |Product 3A |prod-3-A | |9 |Product 3B |prod-3-B | |10 |Product 4 |prod-4 | ---------------------------------------
Sie können auch wie folgt auf Spalten verweisen:
>>> # Import the col function from the functions module. >>> from snowflake.snowpark.functions import col >>> df_product_info = session.table("sample_product_data") >>> df1 = df_product_info.select(df_product_info["id"], df_product_info["name"], df_product_info["serial_number"]) >>> df2 = df_product_info.select(df_product_info.id, df_product_info.name, df_product_info.serial_number) >>> df3 = df_product_info.select("id", "name", "serial_number")
Jede Methode gibt ein neues DataFrame-Objekt zurück, das transformiert wurde. Die Methode hat keine Auswirkungen auf das ursprüngliche DataFrame-Objekt. Wenn Sie mehrere Transformationen anwenden möchten, können Sie Methodenaufrufe verketten, sodass jede nachfolgende Transformationsmethode auf dem neuen DataFrame-Objekt ausgeführt wird, das vom vorherigen Methodenaufruf zurückgegeben wurde.
Diese Transformationsmethoden geben an, wie die SQL-Anweisung erstellt wird, sie rufen keine Daten aus der Snowflake-Datenbank ab. Die unter Ausführen einer Aktion zum Auswerten eines DataFrame beschriebenen Aktionsmethoden führen den Datenabruf aus.
Verknüpfen von DataFrames¶
Zum Verknüpfen von DataFrame-Objekten rufen Sie die join
-Methode auf:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # Create a DataFrame that joins the two DataFrames
>>> # on the column named "key".
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].as_("key"), "value1", "value2").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].as_("key"), "value1", "value2")
-------------------------------
|"KEY" |"VALUE1" |"VALUE2" |
-------------------------------
|a |1 |3 |
|b |2 |4 |
-------------------------------
Wenn beide DataFrames die gleiche Spalte für die Verknüpfung haben, können Sie die folgende Beispielsyntax verwenden:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # If both dataframes have the same column "key", the following is more convenient.
>>> df_lhs.join(df_rhs, ["key"]).show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, ["key"])
-------------------------------
|"KEY" |"VALUE1" |"VALUE2" |
-------------------------------
|a |1 |3 |
|b |2 |4 |
-------------------------------
Sie können auch den &-Operator verwenden, um Join-Ausdrücke zu verbinden:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> # Use & operator connect join expression. '|' and ~ are similar.
>>> df_joined_multi_column = df_lhs.join(df_rhs, (df_lhs.col("key") == df_rhs.col("key")) & (df_lhs.col("value1") < df_rhs.col("value2"))).select(df_lhs["key"].as_("key"), "value1", "value2")
>>> df_joined_multi_column.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_joined_multi_column
-------------------------------
|"KEY" |"VALUE1" |"VALUE2" |
-------------------------------
|a |1 |3 |
|b |2 |4 |
-------------------------------
Wenn Sie eine Selbstverknüpfung (Self-Join) ausführen möchten, müssen Sie den DataFrame kopieren:
>>> # copy the DataFrame if you want to do a self-join
>>> from copy import copy
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs_copied = copy(df_lhs)
>>> df_self_joined = df_lhs.join(df_lhs_copied, (df_lhs.col("key") == df_lhs_copied.col("key")) & (df_lhs.col("value1") == df_lhs_copied.col("value1")))
Wenn es in den DataFrames sich überlappende Spalten gibt, stellt Snowpark den Spalten im Verknüpfungsergebnis ein zufällig generiertes Präfix voran:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"))
-----------------------------------------------------
|"l_av5t_KEY" |"VALUE1" |"r_1p6k_KEY" |"VALUE2" |
-----------------------------------------------------
|a |1 |a |3 |
|b |2 |b |4 |
-----------------------------------------------------
Sie können die überlappenden Spalten mit Column.alias
umbenennen:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].alias("key1"), df_rhs["key"].alias("key2"), "value1", "value2").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs["key"].alias("key1"), df_rhs["key"].alias("key2"), "value1", "value2")
-----------------------------------------
|"KEY1" |"KEY2" |"VALUE1" |"VALUE2" |
-----------------------------------------
|a |a |1 |3 |
|b |b |2 |4 |
-----------------------------------------
Um zufällige Präfixe zu vermeiden, können Sie auch ein Suffix angeben, das an die sich überschneidenden Spalten angehängt wird:
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value1"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value2"])
>>> df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"), lsuffix="_left", rsuffix="_right").show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key"), lsuffix="_left", rsuffix="_right")
--------------------------------------------------
|"KEY_LEFT" |"VALUE1" |"KEY_RIGHT" |"VALUE2" |
--------------------------------------------------
|a |1 |a |3 |
|b |2 |b |4 |
--------------------------------------------------
In diesen Beispielen wird DataFrame.col
verwendet, um die in der Verknüpfung zu verwendenden Spalten anzugeben. Weitere Möglichkeiten zum Angeben von Spalten finden Sie unter Angeben von Spalten und Ausdrücken.
Wenn Sie eine Tabelle mit sich selbst über verschiedene Spalten verknüpfen müssen, können Sie die Selbstverknüpfung (Self-Join) nicht mit einem einzelnen DataFrame durchführen. Im folgenden Beispiel wird ein einzelner DataFrame in einer Selbstverknüpfung verwendet. Diese Ausführung schlägt fehl, weil die Spaltenausdrücke für "id"
sowohl auf der linken als auch der rechten Seite der Verknüpfung vorhanden sind:
>>> from snowflake.snowpark.exceptions import SnowparkJoinException
>>> df = session.table("sample_product_data")
>>> # This fails because columns named "id" and "parent_id"
>>> # are in the left and right DataFrames in the join.
>>> try:
... df_joined = df.join(df, col("id") == col("parent_id")) # fails
... except SnowparkJoinException as e:
... print(e.message)
You cannot join a DataFrame with itself because the column references cannot be resolved correctly. Instead, create a copy of the DataFrame with copy.copy(), and join the DataFrame with this copy.
>>> # This fails because columns named "id" and "parent_id"
>>> # are in the left and right DataFrames in the join.
>>> try:
... df_joined = df.join(df, df["id"] == df["parent_id"]) # fails
... except SnowparkJoinException as e:
... print(e.message)
You cannot join a DataFrame with itself because the column references cannot be resolved correctly. Instead, create a copy of the DataFrame with copy.copy(), and join the DataFrame with this copy.
Verwenden Sie stattdessen die in Python integrierte copy()
-Methode, um einen Klon des DataFrame-Objekts zu erstellen, und verwenden Sie dann die beiden DataFrame-Objekte für die Verknüpfung:
>>> from copy import copy
>>> # Create a DataFrame object for the "sample_product_data" table for the left-hand side of the join.
>>> df_lhs = session.table("sample_product_data")
>>> # Clone the DataFrame object to use as the right-hand side of the join.
>>> df_rhs = copy(df_lhs)
>>> # Create a DataFrame that joins the two DataFrames
>>> # for the "sample_product_data" table on the
>>> # "id" and "parent_id" columns.
>>> df_joined = df_lhs.join(df_rhs, df_lhs.col("id") == df_rhs.col("parent_id"))
>>> df_joined.count()
8
Angeben von Spalten und Ausdrücken¶
Wenn Sie diese Transformationsmethoden aufrufen, müssen Sie möglicherweise Spalten angeben oder Ausdrücke, die Spalten verwenden. Wenn Sie z. B. die select
-Methode aufrufen, müssen Sie die Spalten angeben, die ausgewählt werden sollen.
Um auf eine Spalte zu verweisen, erstellen Sie ein Column
-Objekt durch Aufruf der Funktion col
im snowflake.snowpark.functions
-Modul.
>>> # Import the col function from the functions module.
>>> from snowflake.snowpark.functions import col
>>> df_product_info = session.table("sample_product_data").select(col("id"), col("name"))
>>> df_product_info.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_product_info
---------------------
|"ID" |"NAME" |
---------------------
|1 |Product 1 |
|2 |Product 1A |
|3 |Product 1B |
|4 |Product 2 |
|5 |Product 2A |
|6 |Product 2B |
|7 |Product 3 |
|8 |Product 3A |
|9 |Product 3B |
|10 |Product 4 |
---------------------
Bemerkung
Weitere Informationen zum Erstellen eines Column
-Objekts für ein Literal finden Sie unter Verwenden von Literalen als Spaltenobjekte.
Wenn Sie einen Filter, eine Projektion, eine Verknüpfungsbedingung usw. angeben müssen, können Sie Column
-Objekte in einem Ausdruck verwenden. Beispiel:
Sie können
Column
-Objekte mit der Methodefilter
verwenden, um eine Filterbedingung anzugeben:>>> # Specify the equivalent of "WHERE id = 20" >>> # in a SQL SELECT statement. >>> df_filtered = df.filter(col("id") == 20)
>>> df = session.create_dataframe([[1, 3], [2, 10]], schema=["a", "b"]) >>> # Specify the equivalent of "WHERE a + b < 10" >>> # in a SQL SELECT statement. >>> df_filtered = df.filter((col("a") + col("b")) < 10) >>> df_filtered.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_filtered ------------- |"A" |"B" | ------------- |1 |3 | -------------
Sie können
Column
-Objekte mit der Methodeselect
verwenden, um einen Alias zu definieren:>>> df = session.create_dataframe([[1, 3], [2, 10]], schema=["a", "b"]) >>> # Specify the equivalent of "SELECT b * 10 AS c" >>> # in a SQL SELECT statement. >>> df_selected = df.select((col("b") * 10).as_("c")) >>> df_selected.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_selected ------- |"C" | ------- |30 | |100 | -------
Sie können
Column
Objekte mit der Methodejoin
verwenden, um eine Verknüpfungsbedingung zu definieren:>>> dfX = session.create_dataframe([[1], [2]], schema=["a_in_X"]) >>> dfY = session.create_dataframe([[1], [3]], schema=["b_in_Y"]) >>> # Specify the equivalent of "X JOIN Y on X.a_in_X = Y.b_in_Y" >>> # in a SQL SELECT statement. >>> df_joined = dfX.join(dfY, col("a_in_X") == col("b_in_Y")).select(dfX["a_in_X"].alias("the_joined_column")) >>> df_joined.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_joined ----------------------- |"THE_JOINED_COLUMN" | ----------------------- |1 | -----------------------
Wenn Sie auf Spalten in zwei verschiedenen DataFrame-Objekten verweisen müssen, die denselben Namen haben (z. B. beim Verknüpfen von DataFrames über diese Spalte), können Sie die DataFrame.col
-Methode in einem der beiden DataFrame-Objekte verwenden, um sich auf eine Spalte in diesem Objekt zu beziehen (z. B. df1.col("name")
und df2.col("name")
).
Im folgenden Beispiel wird gezeigt, wie Sie mit der DataFrame.col
-Methode auf eine Spalte in einem bestimmten DataFrame verweisen. Im Beispiel werden zwei DataFrame-Objekte verknüpft, die beide eine Spalte mit dem Namen key
haben. Dabei wird im Beispiel die Column.as
-Methode verwendet, um die Namen der Spalten im neu erstellten DataFrame zu ändern.
>>> # Create two DataFrames to join
>>> df_lhs = session.create_dataframe([["a", 1], ["b", 2]], schema=["key", "value"])
>>> df_rhs = session.create_dataframe([["a", 3], ["b", 4]], schema=["key", "value"])
>>> # Create a DataFrame that joins two other DataFrames (df_lhs and df_rhs).
>>> # Use the DataFrame.col method to refer to the columns used in the join.
>>> df_joined = df_lhs.join(df_rhs, df_lhs.col("key") == df_rhs.col("key")).select(df_lhs.col("key").as_("key"), df_lhs.col("value").as_("L"), df_rhs.col("value").as_("R"))
>>> df_joined.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_joined
---------------------
|"KEY" |"L" |"R" |
---------------------
|a |1 |3 |
|b |2 |4 |
---------------------
Verwenden von doppelten Anführungszeichen um Objektbezeichner (Tabellennamen, Spaltennamen usw.)¶
Die Namen von Datenbanken, Schemas, Tabellen und Stagingbereichen, die Sie angeben, müssen den Snowflake-Anforderungen an Bezeichner entsprechen.
Erstellen Sie eine Tabelle mit Spalten, in denen die Groß-/Kleinschreibung unterschieden wird:
>>> session.sql("""
... create or replace temp table "10tablename"(
... id123 varchar, -- case insensitive because it's not quoted.
... "3rdID" varchar, -- case sensitive.
... "id with space" varchar -- case sensitive.
... )""").collect()
>>> # Add return to the statement to return the collect() results in a Python worksheet
[Row(status='Table 10tablename successfully created.')]
Fügen Sie dann Werte zur Tabelle hinzu:
>>> session.sql("""insert into "10tablename" (id123, "3rdID", "id with space") values ('a', 'b', 'c')""").collect()
>>> # Add return to the statement to return the collect() results in a Python worksheet
[Row(number of rows inserted=1)]
Erstellen Sie dann einen DataFrame für die Tabelle, und fragen Sie die Tabelle ab:
>>> df = session.table('"10tablename"')
>>> df.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df
---------------------------------------
|"ID123" |"3rdID" |"id with space" |
---------------------------------------
|a |b |c |
---------------------------------------
Wenn Sie einen Namen angeben, geht Snowflake davon aus, dass der Name in Großbuchstaben geschrieben ist. Daher sind z. B. die folgenden Aufrufe gleichwertig:
>>> df.select(col("id123")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(ID123='a')]
>>> df.select(col("ID123")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(ID123='a')]
Wenn der Name nicht den Anforderungen für Bezeichner entspricht, müssen Sie den Namen in doppelte Anführungszeichen ("
) setzen. Verwenden Sie einen Backslash (\
) als Escape-Zeichen zum Umschließen von doppelten Anführungszeichen innerhalb von Zeichenfolgenliteralen. Der folgende Tabellenname beginnt z. B. nicht mit einem Buchstaben oder einem Unterstrich, sodass Sie den Namen in doppelte Anführungszeichen setzen müssen:
>>> df = session.table("\"10tablename\"")
Alternativ können Sie anstelle von Backslashes auch einfache Anführungszeichen als Escapezeichen für doppelte Anführungszeichen in einem Zeichenfolgenliteral verwenden.
>>> df = session.table('"10tablename"')
Beachten Sie, dass Sie bei der Angabe des Namens einer Spalte keine doppelten Anführungszeichen um den Namen verwenden müssen. Die Snowpark-Bibliothek schließt Spaltennamen automatisch in doppelte Anführungszeichen ein, wenn der Name nicht den Bezeichneranforderungen entspricht:
>>> df.select(col("3rdID")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(3rdID='b')]
>>> df.select(col("\"3rdID\"")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(3rdID='b')]
Daher sind z. B. die folgenden Aufrufe äquivalent:
>>> df.select(col("id with space")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
>>> df.select(col("\"id with space\"")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
Wenn Sie bereits doppelte Anführungszeichen um einen Spaltennamen hinzugefügt haben, fügt die Bibliothek keine weiteren doppelten Anführungszeichen um den Namen ein.
In einigen Fällen kann der Spaltenname doppelte Anführungszeichen enthalten:
>>> session.sql('''
... create or replace temp table quoted(
... "name_with_""air""_quotes" varchar,
... """column_name_quoted""" varchar
... )''').collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Table QUOTED successfully created.')]
>>> session.sql('''insert into quoted ("name_with_""air""_quotes", """column_name_quoted""") values ('a', 'b')''').collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(number of rows inserted=1)]
Wie unter Anforderungen an Bezeichner erläutert, müssen Sie für jedes doppelte Anführungszeichen innerhalb eines in Anführungszeichen geschriebenen Bezeichners zwei doppelte Anführungszeichen verwenden (z. B. "name_with_""air""_quotes"
und """column_name_quoted"""
):
>>> df_table = session.table("quoted")
>>> df_table.select("\"name_with_\"\"air\"\"_quotes\"").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(name_with_"air"_quotes='a')]
>>> df_table.select("\"\"\"column_name_quoted\"\"\"").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row("column_name_quoted"='b')]
Wenn ein Bezeichner in doppelte Anführungszeichen eingeschlossen ist (unabhängig davon, ob Sie die Anführungszeichen explizit hinzugefügt haben oder die Bibliothek die Anführungszeichen für Sie hinzugefügt hat), berücksichtigt Snowflake die Groß-/Kleinschreibung des Bezeichners:
>>> # The following calls are NOT equivalent!
>>> # The Snowpark library adds double quotes around the column name,
>>> # which makes Snowflake treat the column name as case-sensitive.
>>> df.select(col("id with space")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(id with space='c')]
Im Vergleich zu folgendem Beispiel:
>>> from snowflake.snowpark.exceptions import SnowparkSQLException
>>> try:
... df.select(col("ID WITH SPACE")).collect()
... except SnowparkSQLException as e:
... print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 7
invalid identifier '"ID WITH SPACE"'
Verwenden von Literalen als Spaltenobjekte¶
Um ein Literal in einer Methode zu verwenden, die ein Column
-Objekt als Argument erwartet, erstellen Sie ein Column
-Objekt für das Literal, indem Sie das Literal an die lit
-Funktion im snowflake.snowpark.functions
-Modul übergeben. Beispiel:
>>> # Import for the lit and col functions.
>>> from snowflake.snowpark.functions import col, lit
>>> # Show the first 10 rows in which num_items is greater than 5.
>>> # Use `lit(5)` to create a Column object for the literal 5.
>>> df_filtered = df.filter(col("num_items") > lit(5))
Umwandeln eines Spaltenobjekts in einen bestimmten Typ¶
Um ein Column
-Objekt in einen bestimmten Typ umzuwandeln, rufen Sie die cast
-Methode auf, und übergeben Sie ein Typobjekt aus dem snowflake.snowpark.types
-Modul. So können Sie zum Beispiel ein Literal in NUMBER mit einer Gesamtstellenzahl (precision) von 5 und einer Dezimalstellenzahl (scale) von 2 umwandeln:
>>> # Import for the lit function.
>>> from snowflake.snowpark.functions import lit
>>> # Import for the DecimalType class.
>>> from snowflake.snowpark.types import DecimalType
>>> decimal_value = lit(0.05).cast(DecimalType(5,2))
Verketten von Methodenaufrufen¶
Da jede Methode, die ein DataFrame-Objekt transformiert, ein neues DataFrame-Objekt zurückgibt, auf das die Transformation angewendet wurde, können Sie Methodenaufrufe verketten, um ein neues DataFrame zu erstellen, das auf eine andere Weise transformiert wird.
Im folgenden Beispiel wird ein DataFrame zurückgegeben, der für folgende Aufgaben konfiguriert ist:
Abfragen der Tabelle
sample_product_data
Rückgabe der Zeile mit
id = 1
Auswahl der Spalten
name
undserial_number
>>> df_product_info = session.table("sample_product_data").filter(col("id") == 1).select(col("name"), col("serial_number")) >>> df_product_info.show() >>> # To return the DataFrame as a table in a Python worksheet use return instead of show() >>> # return df_product_info ------------------------------- |"NAME" |"SERIAL_NUMBER" | ------------------------------- |Product 1 |prod-1 | -------------------------------
In diesem Beispiel:
session.table("sample_product_data")
gibt einen DataFrame für die Tabellesample_product_data
zurück.Der DataFrame enthält zwar noch nicht die Daten aus der Tabelle, aber das Objekt enthält die Definitionen der Spalten in der Tabelle.
filter(col("id") == 1)
gibt ein DataFrame für die Tabellesample_product_data
zurück, die so eingerichtet ist, dass sie die Zeile mitid = 1
zurückgibt.Beachten Sie, dass der DataFrame noch nicht die übereinstimmende Zeile aus der Tabelle enthält. Die übereinstimmende Zeile wird erst abgerufen, wenn Sie eine Aktionsmethode aufrufen.
select(col("name"), col("serial_number"))
gibt ein DataFrame zurück, das die Spaltenname
undserial_number
für die Zeile in der Tabellesample_product_data
enthält, dieid = 1
hat.
Beim Verketten von Methodenaufrufen ist die Reihenfolge der Aufrufe von Bedeutung. Jeder Methodenaufruf gibt ein DataFrame zurück, das transformiert wurde. Stellen Sie sicher, dass nachfolgende Aufrufe das transformierte DataFrame verwenden.
Im folgenden Beispiel gibt die Methode select
ein DataFrame zurück, das nur zwei Spalten enthält: name
und serial_number
. Der Aufruf der filter
-Methode auf diesem DataFrame schlägt fehl, weil dieser die Spalte id
verwendet, die im transformierten DataFrame nicht vorhanden ist.
>>> # This fails with the error "invalid identifier 'ID'."
>>> df_product_info = session.table("sample_product_data").select(col("name"), col("serial_number")).filter(col("id") == 1)
>>> try:
... df_product_info.show()
... except SnowparkSQLException as e:
... print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 121
invalid identifier 'ID'
Im Gegensatz dazu wird der folgende Code erfolgreich ausgeführt, weil die filter()
-Methode auf einem DataFrame aufgerufen wird, der alle Spalten der Tabelle sample_product_data
einschließlich der Spalte id
enthält:
>>> # This succeeds because the DataFrame returned by the table() method
>>> # includes the "id" column.
>>> df_product_info = session.table("sample_product_data").filter(col("id") == 1).select(col("name"), col("serial_number"))
>>> df_product_info.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_product_info
-------------------------------
|"NAME" |"SERIAL_NUMBER" |
-------------------------------
|Product 1 |prod-1 |
-------------------------------
Beim Verwenden von Snowpark Python müssen Sie die Methodenaufrufe select
und filter
möglicherweise in einer anderen Reihenfolge ausführen als bei Verwendung der entsprechenden Schlüsselwörter (SELECT und WHERE) in einer SQL-Anweisung.
Abrufen von Spaltendefinitionen¶
Um die Definition der Spalten im Dataset für den DataFrame abzurufen, rufen Sie die schema
-Eigenschaft auf. Diese Methode gibt ein StructType
-Objekt zurück, das ein list
von StructField
-Objekten enthält. Jedes StructField
-Objekt enthält die Definition einer Spalte.
# Import the StructType
from snowflake.snowpark.types import *
# Get the StructType object that describes the columns in the
# underlying rowset.
table_schema = session.table("sample_product_data").schema
table_schema
StructType([StructField('ID', LongType(), nullable=True), StructField('PARENT_ID', LongType(), nullable=True), StructField('CATEGORY_ID', LongType(), nullable=True), StructField('NAME', StringType(), nullable=True), StructField('SERIAL_NUMBER', StringType(), nullable=True), StructField('KEY', LongType(), nullable=True), StructField('"3rd"', LongType(), nullable=True)])
Im zurückgegebenen StructType
-Objekt sind die Spaltennamen immer normalisiert. Bezeichner, die nicht mit Anführungszeichen umschlossen sind, werden in Großbuchstaben zurückgegeben. Bezeichner in Anführungszeichen werden genau in der Schreibweise zurückgegeben, in der sie definiert wurden.
Im folgenden Beispiel wird ein DataFrame erstellt zurück, der die Spalten mit den Namen ID
und 3rd
enthält. Für den Spaltennamen 3rd
schließt die Snowpark-Bibliothek den Namen automatisch in doppelte Anführungszeichen ein ("3rd"
), da der Name nicht den Anforderungen an einen Bezeichner entspricht.
Im Beispiel wird erst die schema
-Eigenschaft aufgerufen und dann die names
-Eigenschaft auf dem zurückgegebenen StructType
-Objekt, um ein list
-Objekt mit den Spaltennamen zu erhalten. Die Namen werden in dem von der schema
-Eigenschaft zurückgegebenen StructType
-Objekt normalisiert.
>>> # Create a DataFrame containing the "id" and "3rd" columns.
>>> df_selected_columns = session.table("sample_product_data").select(col("id"), col("3rd"))
>>> # Print out the names of the columns in the schema. This prints out:
>>> # This prints List["ID", "\"3rd\""]
>>> df_selected_columns.schema.names
['ID', '"3rd"']
Ausführen einer Aktion zum Auswerten eines DataFrame¶
Wie bereits erwähnt, wird der DataFrame im Lazy-Modus ausgewertet, d. h. die SQL-Anweisung wird erst dann zur Ausführung an den Server gesendet, wenn Sie eine Aktion ausführen. Eine Aktion löst die Auswertung des DataFrame aus und sendet die entsprechende SQL-Anweisung zur Ausführung an den Server.
Die folgenden Methoden führen eine Aktion aus:
Klasse |
Methode |
Beschreibung |
---|---|---|
|
|
Wertet den DataFrame aus und gibt das resultierende Dataset als ein |
|
|
Wertet den DataFrame aus und gibt die Anzahl der Zeilen zurück. |
|
|
Wertet den DataFrame aus und gibt die Zeilen auf der Konsole aus. Bei dieser Methode ist die Anzahl der Zeilen (standardmäßig) auf 10 begrenzt. |
|
|
Speichert die im DataFrame enthaltenen Daten in die angegebene Tabelle. Weitere Informationen dazu finden Sie unter Speichern von Daten in eine Tabelle. |
Beispiel: Um eine Abfrage auf einer Tabelle auszuführen und die Ergebnisse zurückzugeben, rufen Sie die collect
-Methode auf:
>>> # Create a DataFrame with the "id" and "name" columns from the "sample_product_data" table.
>>> # This does not execute the query.
>>> df = session.table("sample_product_data").select(col("id"), col("name"))
>>> # Send the query to the server for execution and
>>> # return a list of Rows containing the results.
>>> results = df.collect()
>>> # Use a return statement to return the collect() results in a Python worksheet
>>> # return results
Um die Abfrage auszuführen und die Anzahl der Ergebnisse zurückzugeben, rufen Sie die count
-Methode auf:
>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")
>>> # Send the query to the server for execution and
>>> # print the count of rows in the table.
>>> print(df_products.count())
12
Um eine Abfrage auszuführen und die Ergebnisse über die Konsole auszugeben, rufen Sie die show
-Methode auf:
>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")
>>> # Send the query to the server for execution and
>>> # print the results to the console.
>>> # The query limits the number of rows to 10 by default.
>>> df_products.show()
>>> # To return the DataFrame as a table in a Python worksheet use return instead of show()
>>> # return df_products
-------------------------------------------------------------------------------------
|"ID" |"PARENT_ID" |"CATEGORY_ID" |"NAME" |"SERIAL_NUMBER" |"KEY" |"3rd" |
-------------------------------------------------------------------------------------
|1 |0 |5 |Product 1 |prod-1 |1 |10 |
|2 |1 |5 |Product 1A |prod-1-A |1 |20 |
|3 |1 |5 |Product 1B |prod-1-B |1 |30 |
|4 |0 |10 |Product 2 |prod-2 |2 |40 |
|5 |4 |10 |Product 2A |prod-2-A |2 |50 |
|6 |4 |10 |Product 2B |prod-2-B |2 |60 |
|7 |0 |20 |Product 3 |prod-3 |3 |70 |
|8 |7 |20 |Product 3A |prod-3-A |3 |80 |
|9 |7 |20 |Product 3B |prod-3-B |3 |90 |
|10 |0 |50 |Product 4 |prod-4 |4 |100 |
-------------------------------------------------------------------------------------
So begrenzen Sie die Anzahl der Zeilen auf 20:
>>> # Create a DataFrame for the "sample_product_data" table.
>>> df_products = session.table("sample_product_data")
>>> # Limit the number of rows to 20, rather than 10.
>>> df_products.show(20)
>>> # All rows are returned when you use return in a Python worksheet to return the DataFrame as a table
>>> # return df_products
-------------------------------------------------------------------------------------
|"ID" |"PARENT_ID" |"CATEGORY_ID" |"NAME" |"SERIAL_NUMBER" |"KEY" |"3rd" |
-------------------------------------------------------------------------------------
|1 |0 |5 |Product 1 |prod-1 |1 |10 |
|2 |1 |5 |Product 1A |prod-1-A |1 |20 |
|3 |1 |5 |Product 1B |prod-1-B |1 |30 |
|4 |0 |10 |Product 2 |prod-2 |2 |40 |
|5 |4 |10 |Product 2A |prod-2-A |2 |50 |
|6 |4 |10 |Product 2B |prod-2-B |2 |60 |
|7 |0 |20 |Product 3 |prod-3 |3 |70 |
|8 |7 |20 |Product 3A |prod-3-A |3 |80 |
|9 |7 |20 |Product 3B |prod-3-B |3 |90 |
|10 |0 |50 |Product 4 |prod-4 |4 |100 |
|11 |10 |50 |Product 4A |prod-4-A |4 |100 |
|12 |10 |50 |Product 4B |prod-4-B |4 |100 |
-------------------------------------------------------------------------------------
Bemerkung
Wenn Sie die schema
-Eigenschaft aufrufen, um die Definitionen der Spalten im DataFrame zu erhalten, müssen Sie keine Aktionsmethode aufrufen.
Inhalt des DataFrame als Pandas DataFrame zurückgeben¶
Um den Inhalt eines DataFrame als Pandas DataFrame zurückzugeben, verwenden Sie die to_pandas
-Methode.
Beispiel:
>>> python_df = session.create_dataframe(["a", "b", "c"])
>>> pandas_df = python_df.to_pandas()
Speichern von Daten in eine Tabelle¶
So speichern Sie den Inhalt eines DataFrame in eine Tabelle:
Rufen Sie die Eigenschaft
write
auf, um einDataFrameWriter
-Objekt zu erhalten.Rufen Sie die Methode
mode
im ObjektDataFrameWriter
auf, und geben Sie den Modus an. Weitere Informationen dazu finden Sie in der API-Dokumentation. Diese Methode gibt ein neuesDataFrameWriter
-Objekt zurück, das mit dem angegebenen Modus konfiguriert ist.Rufen Sie die Methode
save_as_table
imDataFrameWriter
-Objekt auf, um den Inhalt des DataFrame in der angegebenen Tabelle zu speichern.
Beachten Sie, dass Sie keine separate Methode (z. B. collect
) aufrufen müssen, um die SQL-Anweisung auszuführen, mit der Daten in der Tabelle gespeichert werden.
Beispiel:
>>> df.write.mode("overwrite").save_as_table("table1")
Erstellen einer Ansicht aus einem DataFrame¶
Um aus einem DataFrame eine Ansicht zu erstellen, rufen Sie die Methode create_or_replace_view
auf, die unmittelbar eine neue Ansicht erstellt:
>>> import os
>>> database = os.environ["snowflake_database"] # use your own database and schema
>>> schema = os.environ["snowflake_schema"]
>>> view_name = "my_view"
>>> df.create_or_replace_view(f"{database}.{schema}.{view_name}")
[Row(status='View MY_VIEW successfully created.')]
Da Sie das Arbeitsblatt in einem Python-Arbeitsblatt im Kontext einer Datenbank und eines Schemas ausführen, können Sie zum Erstellen einer Ansicht Folgendes ausführen:
# Define a DataFrame
df_products = session.table("sample_product_data")
# Define a View name
view_name = "my_view"
# Create the view
df_products.create_or_replace_view(f"{view_name}")
# return the view name
return view_name + " successfully created"
my_view successfully created
Ansichten, die Sie durch Aufruf von create_or_replace_view
erstellen, sind persistent. Wenn Sie diese Ansicht nicht mehr benötigen, können Sie die Ansicht manuell löschen.
Alternativ können Sie auch die Methode create_or_replace_temp_view
verwenden, die eine temporäre Ansicht erstellt. Die temporäre Ansicht ist nur in der Sitzung verfügbar, in der sie erstellt wurde.
Verwenden von Dateien in Stagingbereichen¶
In diesem Abschnitt wird erläutert, wie Sie Daten in einer Datei abfragen, die sich in einem Snowflake-Stagingbereich befindet. Für andere Operationen auf Dateien verwenden Sie SQL-Anweisungen.
Um Daten in Dateien abzufragen, die sich in einem Snowflake-Stagingbereich befinden, verwenden Sie die Klasse DataFrameReader
:
Rufen Sie die Methode
read
derSession
-Klasse auf, um auf einDataFrameReader
-Objekt zuzugreifen.Wenn die Dateien im CSV-Format sind, beschreiben Sie die Felder in der Datei. Gehen Sie dabei wie folgt vor:
Erstellen Sie ein
StructType
-Objekt, das aus einemlist
-Objekt vonStructField
-Objekten besteht, die die Felder in der Datei beschreiben.Geben Sie für jedes
StructField
-Objekt Folgendes an:Name des Feldes
Datentyp des Feldes (angegeben als Objekt im
snowflake.snowpark.types
-Modul)Ob das Feld nullwertfähig ist oder nicht
Beispiel:
>>> from snowflake.snowpark.types import * >>> schema_for_data_file = StructType([ ... StructField("id", StringType()), ... StructField("name", StringType()) ... ])
Rufen Sie die
schema
-Eigenschaft imDataFrameReader
-Objekt auf, und übergeben Sie dabei dasStructType
-Objekt.Beispiel:
>>> df_reader = session.read.schema(schema_for_data_file)
Die
schema
-Methode gibt einDataFrameReader
-Objekt zurück, das so konfiguriert ist, dass es Dateien liest, die die angegebenen Felder enthalten.Beachten Sie, dass Sie dies für Dateien in anderen Formaten (z. B. JSON) nicht tun müssen. Für solche Dateien behandelt der
DataFrameReader
die Daten als ein einzelnes Feld vom Typ VARIANT mit dem Feldnamen$1
.
Wenn Sie zusätzliche Informationen darüber angeben müssen, wie die Daten gelesen werden sollen (z. B. dass die Daten komprimiert sind oder dass eine CSV-Datei ein Semikolon statt eines Kommas zum Begrenzen von Feldern verwendet), rufen Sie die Methode
option
oderoptions
desDataFrameReader
-Objekts auf.Die
option
-Methode nimmt den Namen und den Wert der Option entgegen, die Sie festlegen möchten, und ermöglicht es Ihnen, mehrere verkettete Aufrufe zu kombinieren, während dieoptions
-Methode ein Wörterbuch mit den Namen der Optionen und den entsprechenden Werten annimmt.Die Namen und Werte der Dateiformatoptionen finden Sie in der Dokumentation zu CREATE FILE FORMAT.
Sie können auch die in der COPY INTO TABLE-Dokumentation beschriebenen Kopieroptionen einstellen. Beachten Sie, dass die Einstellung von Kopieroptionen zu einer teureren Ausführungsstrategie führen kann, wenn Sie die Daten in den DataFrame abrufen.
Im folgenden Beispiel wird das
DataFrameReader
-Objekt für die Abfrage von Daten einer CSV-Datei eingerichtet, die nicht komprimiert ist und die ein Semikolon als Feldbegrenzer verwendet.>>> df_reader = df_reader.option("field_delimiter", ";").option("COMPRESSION", "NONE")
Die Methoden
option
undoptions
geben einDataFrameReader
-Objekt zurück, das mit den angegebenen Optionen konfiguriert ist.Rufen Sie die Methode auf, die dem Format der Datei entspricht (z. B. die Methode
csv
), und übergeben Sie dabei den Speicherort der Datei.>>> df = df_reader.csv("@s3_ts_stage/emails/data_0_0_0.csv")
Die Methoden, die dem Format einer Datei entsprechen, geben ein DataFrame-Objekt zurück, das so konfiguriert ist, dass es die Daten aus dieser Datei enthält.
Verwenden Sie die DataFrame-Objektmethoden, um alle Transformationen auszuführen, die für das Dataset benötigt werden (Auswahl bestimmter Felder, Filtern von Zeilen usw.).
Im folgenden Beispiel wird das Element
color
aus einer JSON-Datei extrahiert, die sich im Stagingbereichmy_stage
befindet:>>> # Import the sql_expr function from the functions module. >>> from snowflake.snowpark.functions import sql_expr >>> df = session.read.json("@my_stage").select(sql_expr("$1:color"))
Wie bereits erläutert, werden Daten in Dateien, die nicht im CSV-Format sind (z. B. JSON), von
DataFrameReader
als eine einzelne VARIANT-Spalte mit dem Namen$1
behandelt.In diesem Beispiel wird die Funktion
sql_expr
imsnowflake.snowpark.functions
-Modul verwendet, um den Pfad zum Elementcolor
anzugeben.Beachten Sie, dass die Funktion
sql_expr
das Eingangsargument weder interpretiert noch verändert. Mit der Funktion können Sie lediglich Ausdrücke und Snippets in SQL konstruieren, die noch nicht von der Snowpark-API unterstützt werden.Rufen Sie eine Aktionsmethode auf, um die Daten in der Datei abzufragen.
Wie bei DataFrames für Tabellen werden die Daten erst dann in den DataFrame abgerufen, wenn Sie eine Aktionsmethode aufrufen.
Verwenden von semistrukturierten Daten¶
Mit einem DataFrame können Sie semistrukturierte Daten abfragen und darauf zugreifen (z. B. JSON-Daten). In den nächsten Abschnitten wird erläutert, wie semistrukturierte Daten in einem DataFrame verwendet werden:
Bemerkung
Die Beispiele in diesen Abschnitten verwenden die Beispieldaten aus In Beispielen verwendete Beispieldaten.
Durchsuchen semistrukturierter Daten¶
Um auf ein bestimmtes Feld oder Element in semistrukturierten Daten zu verweisen, verwenden Sie die folgenden Methoden des Column
-Objekts:
Rufen Sie das Attribut
col_object["<Feldname>"]
ab, um einColumn
-Objekt für ein Feld in einem OBJECT (oder ein VARIANT, das ein OBJECT enthält) zurückzugeben.Verwenden Sie
col_object[<Index>]
, um einColumn
-Objekt für ein Element in einem ARRAY (oder ein VARIANT, das ein ARRAY enthält) zurückzugeben.
Bemerkung
Wenn der Feldname oder die Elemente im Pfad unregelmäßig sind und die Verwendung der oben beschriebenen Indexierung erschweren, können Sie als Alternative get
, get_ignore_case
oder get_path
verwenden.
Im folgenden Code wird beispielsweise das Feld dealership
in Objekten der Spalte src
der Beispieldaten ausgewählt:
>>> from snowflake.snowpark.functions import col
>>> df = session.table("car_sales")
>>> df.select(col("src")["dealership"]).show()
Der Code gibt Folgendes aus:
----------------------------
|"""SRC""['DEALERSHIP']" |
----------------------------
|"Valley View Auto Sales" |
|"Tindel Toyota" |
----------------------------
Bemerkung
Die Werte in DataFrame sind von doppelten Anführungszeichen umgeben, da diese Werte als Zeichenfolgenliterale zurückgegeben werden. Weitere Informationen zum Umwandeln dieser Werte in einen bestimmten Typ finden Sie unter Explizites Umwandeln von Werten semistrukturierter Daten.
Sie können auch Methodenaufrufe verketten, um einen Pfad zu einem bestimmten Feld oder Element zu durchlaufen.
Im folgende Code wird zum Beispiel das Feld name
im Objekt salesperson
ausgewählt:
>>> df = session.table("car_sales")
>>> df.select(df["src"]["salesperson"]["name"]).show()
Der Code gibt Folgendes aus:
------------------------------------
|"""SRC""['SALESPERSON']['NAME']" |
------------------------------------
|"Frank Beasley" |
|"Greg Northrup" |
------------------------------------
In einem weiteren Codebeispiel wird das erste Element des Feldes vehicle
ausgewählt, das eine Reihe von Fahrzeugen enthält. Im Beispiel wird auch das Feld price
aus dem ersten Element ausgewählt.
>>> df = session.table("car_sales")
>>> df.select(df["src"]["vehicle"][0]).show()
>>> df.select(df["src"]["vehicle"][0]["price"]).show()
Der Code gibt Folgendes aus:
---------------------------
|"""SRC""['VEHICLE'][0]" |
---------------------------
|{ |
| "extras": [ |
| "ext warranty", |
| "paint protection" |
| ], |
| "make": "Honda", |
| "model": "Civic", |
| "price": "20275", |
| "year": "2017" |
|} |
|{ |
| "extras": [ |
| "ext warranty", |
| "rust proofing", |
| "fabric protection" |
| ], |
| "make": "Toyota", |
| "model": "Camry", |
| "price": "23500", |
| "year": "2017" |
|} |
---------------------------
------------------------------------
|"""SRC""['VEHICLE'][0]['PRICE']" |
------------------------------------
|"20275" |
|"23500" |
------------------------------------
Wenn der Feldname oder die Elemente im Pfad unregelmäßig sind, können Sie für den oben beschriebenen Zugriff auf Felder alternativ auch die Funktion get
, get_ignore_case
oder get_path
verwenden.
Die folgenden Codezeilen geben zum Beispiel beide den Wert eines bestimmten Feldes in einem Objekt aus:
>>> from snowflake.snowpark.functions import get, get_path, lit
>>> df.select(get(col("src"), lit("dealership"))).show()
>>> df.select(col("src")["dealership"]).show()
In ähnlicher Weise geben die folgenden Codezeilen beide den Wert eines Feldes für einen bestimmten Pfad in einem Objekt aus:
>>> df.select(get_path(col("src"), lit("vehicle[0].make"))).show()
>>> df.select(col("src")["vehicle"][0]["make"]).show()
Explizites Umwandeln von Werten semistrukturierter Daten¶
Standardmäßig werden die Werte von Feldern und Elementen als Zeichenfolgenliterale (einschließlich der doppelten Anführungszeichen) zurückgegeben, wie in den obigen Beispielen gezeigt.
Um unerwartete Ergebnisse zu vermeiden, rufen Sie die Methode cast auf, um den Wert in einen ganz bestimmten Typ umzuwandeln. Mit dem folgenden Code werden zum Beispiel die Werte ohne und mit Umwandlung ausgegeben:
>>> # Import the objects for the data types, including StringType.
>>> from snowflake.snowpark.types import *
>>> df = session.table("car_sales")
>>> df.select(col("src")["salesperson"]["id"]).show()
>>> df.select(col("src")["salesperson"]["id"].cast(StringType())).show()
Der Code gibt Folgendes aus:
----------------------------------
|"""SRC""['SALESPERSON']['ID']" |
----------------------------------
|"55" |
|"274" |
----------------------------------
---------------------------------------------------
|"CAST (""SRC""['SALESPERSON']['ID'] AS STRING)" |
---------------------------------------------------
|55 |
|274 |
---------------------------------------------------
Vereinfachen eines Arrays von Objekten zu Zeilen¶
Wenn Sie semistrukturierte Daten für einen DataFrame vereinfachen müssen (um z. B. für jedes Objekt in einem Array eine Zeile zu erstellen), rufen Sie flatten
unter Verwendung der Methode join_table_function
auf. Diese Methode entspricht der SQL-Funktion FLATTEN. Wenn Sie einen Pfad zu einem Objekt oder Array übergeben, gibt die Methode ein DataFrame zurück, das eine Zeile für jedes Feld oder Element im Objekt oder Array enthält.
In den Beispieldaten ist beispielsweise src:customer
ein Array von Objekten, die Informationen über einen Kunden enthalten. Jedes Objekt enthält ein Feld name
und ein Feld address
.
Wenn Sie diesen Pfad an die Funktion flatten
übergeben:
>>> df = session.table("car_sales")
>>> df.join_table_function("flatten", col("src")["customer"]).show()
Dann gibt diese Methode einen DataFrame zurück:
----------------------------------------------------------------------------------------------------------------------------------------------------------
|"SRC" |"SEQ" |"KEY" |"PATH" |"INDEX" |"VALUE" |"THIS" |
----------------------------------------------------------------------------------------------------------------------------------------------------------
|{ |1 |NULL |[0] |0 |{ |[ |
| "customer": [ | | | | | "address": "San Francisco, CA", | { |
| { | | | | | "name": "Joyce Ridgely", | "address": "San Francisco, CA", |
| "address": "San Francisco, CA", | | | | | "phone": "16504378889" | "name": "Joyce Ridgely", |
| "name": "Joyce Ridgely", | | | | |} | "phone": "16504378889" |
| "phone": "16504378889" | | | | | | } |
| } | | | | | |] |
| ], | | | | | | |
| "date": "2017-04-28", | | | | | | |
| "dealership": "Valley View Auto Sales", | | | | | | |
| "salesperson": { | | | | | | |
| "id": "55", | | | | | | |
| "name": "Frank Beasley" | | | | | | |
| }, | | | | | | |
| "vehicle": [ | | | | | | |
| { | | | | | | |
| "extras": [ | | | | | | |
| "ext warranty", | | | | | | |
| "paint protection" | | | | | | |
| ], | | | | | | |
| "make": "Honda", | | | | | | |
| "model": "Civic", | | | | | | |
| "price": "20275", | | | | | | |
| "year": "2017" | | | | | | |
| } | | | | | | |
| ] | | | | | | |
|} | | | | | | |
|{ |2 |NULL |[0] |0 |{ |[ |
| "customer": [ | | | | | "address": "New York, NY", | { |
| { | | | | | "name": "Bradley Greenbloom", | "address": "New York, NY", |
| "address": "New York, NY", | | | | | "phone": "12127593751" | "name": "Bradley Greenbloom", |
| "name": "Bradley Greenbloom", | | | | |} | "phone": "12127593751" |
| "phone": "12127593751" | | | | | | } |
| } | | | | | |] |
| ], | | | | | | |
| "date": "2017-04-28", | | | | | | |
| "dealership": "Tindel Toyota", | | | | | | |
| "salesperson": { | | | | | | |
| "id": "274", | | | | | | |
| "name": "Greg Northrup" | | | | | | |
| }, | | | | | | |
| "vehicle": [ | | | | | | |
| { | | | | | | |
| "extras": [ | | | | | | |
| "ext warranty", | | | | | | |
| "rust proofing", | | | | | | |
| "fabric protection" | | | | | | |
| ], | | | | | | |
| "make": "Toyota", | | | | | | |
| "model": "Camry", | | | | | | |
| "price": "23500", | | | | | | |
| "year": "2017" | | | | | | |
| } | | | | | | |
| ] | | | | | | |
|} | | | | | | |
----------------------------------------------------------------------------------------------------------------------------------------------------------
Von diesem DataFrame aus können Sie die Felder name
und address
jedes Objekts im Feld VALUE
auswählen:
>>> df.join_table_function("flatten", col("src")["customer"]).select(col("value")["name"], col("value")["address"]).show()
-------------------------------------------------
|"""VALUE""['NAME']" |"""VALUE""['ADDRESS']" |
-------------------------------------------------
|"Joyce Ridgely" |"San Francisco, CA" |
|"Bradley Greenbloom" |"New York, NY" |
-------------------------------------------------
Der folgende Code ergänzt das vorherige Beispiel, indem die Werte in einen bestimmten Typ umgewandelt und die Namen der Spalten geändert werden:
>>> df.join_table_function("flatten", col("src")["customer"]).select(col("value")["name"].cast(StringType()).as_("Customer Name"), col("value")["address"].cast(StringType()).as_("Customer Address")).show()
-------------------------------------------
|"Customer Name" |"Customer Address" |
-------------------------------------------
|Joyce Ridgely |San Francisco, CA |
|Bradley Greenbloom |New York, NY |
-------------------------------------------
Ausführen von SQL-Anweisungen¶
Um eine von Ihnen angegebene SQL-Anweisung auszuführen, rufen Sie die Methode sql
in der Klasse Session
auf und übergeben die auszuführende Anweisung. Diese Methode gibt einen DataFrame zurück.
Beachten Sie, dass die SQL-Anweisung erst ausgeführt wird, wenn Sie eine Aktionsmethode aufrufen.
>>> # Get the list of the files in a stage.
>>> # The collect() method causes this SQL statement to be executed.
>>> session.sql("create or replace temp stage my_stage").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Stage area MY_STAGE successfully created.')]
>>> stage_files_df = session.sql("ls @my_stage").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
>>> # Resume the operation of a warehouse.
>>> # Note that you must call the collect method to execute
>>> # the SQL statement.
>>> session.sql("alter warehouse if exists my_warehouse resume if suspended").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Statement executed successfully.')]
>>> # Set up a SQL statement to copy data from a stage to a table.
>>> session.sql("copy into sample_product_data from @my_stage file_format=(type = csv)").collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
[Row(status='Copy executed with 0 files processed.')]
Wenn Sie Methoden zur Transformation des DataFrame aufrufen möchten (z. B. filter
, select
usw.), beachten Sie, dass diese Methoden nur funktionieren, wenn die zugrunde liegende SQL-Anweisung eine SELECT-Anweisung ist. Die Transformationsmethoden werden für andere Arten von SQL-Anweisungen nicht unterstützt.
>>> df = session.sql("select id, parent_id from sample_product_data where id < 10")
>>> # Because the underlying SQL statement for the DataFrame is a SELECT statement,
>>> # you can call the filter method to transform this DataFrame.
>>> results = df.filter(col("id") < 3).select(col("id")).collect()
>>> # Prepend a return statement to return the collect() results in a Python worksheet
>>> # In this example, the underlying SQL statement is not a SELECT statement.
>>> df = session.sql("ls @my_stage")
>>> # Calling the filter method results in an error.
>>> try:
... df.filter(col("size") > 50).collect()
... except SnowparkSQLException as e:
... print(e.message)
000904 (42000): SQL compilation error: error line 1 at position 104
invalid identifier 'SIZE'