Abläufe mit mehreren Schritten gestalten¶
Übersicht¶
Die meisten Clean Room-Anwendungen beinhalten die Ausführung einer einzelnen SQL-Abfrage auf einer oder mehreren Tabellen in einem Clean Room und die Anzeige der Ergebnisse in der Antwort. Es gibt jedoch viele Anwendungsfälle, in denen Sie Ihren Ablauf in mehrere Schritte aufteilen möchten, die nacheinander oder in beliebiger Reihenfolge ausgeführt werden können und den Aufruf von Python-Code zur Verarbeitung (oder Vorverarbeitung) der Daten beinhalten können. Beispiele hierfür sind maschinelles Lernen, bei dem Daten einmal anhand eines Datensatzes trainiert werden und dann mehrfach anhand unterschiedlicher Eingabedaten ausgeführt werden, entweder einzeln oder in Batches.
Clean Rooms verfügen über mehrere Mechanismen, die diese erweiterten Szenarien ermöglichen:
Vorlagenketten: Eine Vorlagenkette führt eine Reihe von Vorlagen in einer bestimmten Reihenfolge aus, wobei die Ausgabe jeder Vorlage als Eingabe für die nächste Vorlage verwendet wird. Die Eingabe für die erste Vorlage in der Kette wird vom Benutzer bereitgestellt; die Ausgabe der letzten Vorlage in der Kette wird an den Benutzer zurückgegeben.
Interne Tabellen: Ihre Vorlage oder benutzerdefinierte interne Funktionen können Tabellen innerhalb eines Clean Room erstellen. Diese Tabellen verhalten sich wie verknüpfte Tabellen, da sie für Vorlagen oder benutzerdefinierten hochgeladenen Code zugänglich sind. Interne Tabellen sind nützlich, um den Status oder Daten zu verwalten. Im Beispiel für maschinelles Lernen würden die Trainingsdaten in einer internen Tabelle gespeichert und von internen Funktionen verwendet werden. Auf diese Tabellen kann nur über Vorlagen oder hochgeladenen Code innerhalb des Clean Room zugegriffen werden. Die Speicherung von Zwischendaten in internen Tabellen ist viel effizienter als die Übertragung großer Informationsblöcke in den und aus dem Clean Room mithilfe von Vorlagen.
Benutzerdefinierte interne Funktionen: Sie können benutzerdefinierte Funktionen innerhalb eines Clean Room definieren, die von Vorlagen in diesem Clean Room aufgerufen werden können. Funktionen können in einem Clean Room definiert werden, indem Sie entweder Python-UDFs oder UDTFs in den Clean Room hochladen oder indem Sie einen Containerdienst in Ihrem Clean Room erstellen, der Endpunkte bereitstellt, die Funktionen implementieren. Diese Funktionen können nur von Vorlagen innerhalb des Clean Room aufgerufen werden.
Bemerkung
Ein gemeinsames Prinzip aller Mechanismen ist, dass der Zugriff auf und die Ausführung von Tabellen und Funktionen über eine Vorlage erfolgt. Sie können nicht direkt auf eine interne Clean Room-Tabelle zugreifen, eine benutzerdefinierte Clean Roomfunktion ausführen oder auf einen internen Clean Room Endpunkt zugreifen, sondern nur über eine Vorlage.
Interne Clean Room-Tabellen¶
Sie können innerhalb eines Clean Room mit SQL oder Python Tabellen erstellen, um Zwischenergebnisse zu speichern oder um sie für den Benutzer oder Ihre internen Funktionen (z. B. Trainingsdaten) dauerhaft zu speichern. Diese Tabellen verhalten sich genauso wie verknüpfte Tabellen, mit den folgenden Anmerkungen:
Diese Tabellen werden mithilfe einer Clean Room-Vorlage oder einer UDF/UDTF erstellt und haben keine Verknüpfung mit externen Tabellen.
Diese Tabellen sollten im Namespace
cleanroom
erstellt werden.Sie können Zeilen- und Spaltenrichtlinien für manuell erstellte interne Tabellen festlegen, nachdem Sie sie erstellt haben.
Wenn der Tabellenname nicht statisch ist und andere Vorlagen oder Code auf die Tabelle zugreifen müssen, sollten Sie den Namen der Tabelle an den Benutzer zurückgeben, damit dieser den Namen der dynamischen Tabelle an andere Vorlagen weitergeben kann, die auf diese Tabelle zugreifen müssen.
Hier sind einige Beispiele für die Erstellung einer internen Tabelle:
Eine JinjaSQL-Vorlage kann eine interne Tabelle erstellen, was bei einigen Typen der Aktivierung geschieht.
CALL samooha_by_snowflake_local_db.provider.add_custom_sql_template(
$cleanroom_name,
$template_name,
$$
BEGIN
CREATE OR REPLACE TABLE cleanroom.activation_data_analysis_results AS
SELECT count(*) AS ITEM_COUNT, c.status, c.age_band
FROM IDENTIFIER({{ my_table[0] }}) AS c
JOIN IDENTIFIER({{ source_table[0] }}) AS p
ON {{ c_join_col | sqlsafe | activation_policy }} = {{ p_join_col | sqlsafe | activation_policy }}
GROUP BY c.status, c.age_band
ORDER BY c.age_band;
RETURN 'analysis_results';
END;
$$);
Eine UDF kann eine interne Tabelle erstellen. Dies geschieht in der Regel durch die Ausführung von SQL in Python.
# Snippet of Python UDF to save results to an internal table.
table_name = f'cleanroom.results'
session.sql(f"""
CREATE OR REPLACE TABLE {table_name} AS (
WITH joint_data AS (
SELECT
date,
p.hashed_email AS hem,
impression_id
FROM {source_table} p
)
SELECT
date,
COUNT(DISTINCT hem) AS reach,
COUNT(DISTINCT impression_id) AS num_impressions
FROM joint_data
GROUP BY date
ORDER BY date
);
""").collect()
# Snippet of container services Python code to create an internal results table.
# 'cleanroom' table name prefix is added using the schema parameter when the table is created.
@app.post("/score")
def score():
... omitted content ...
df = pd.DataFrame({
"ID": ids,
"SCORE": scores
})
table = "LOOKALIKE_RESULTS"
session.write_pandas(df, table, schema="CLEANROOM", auto_create_table=True, overwrite=True)
end_time = time.perf_counter()
execution_time = end_time - start_time
response = make_json_response([[0, {"results_table": table, "size": len(ids), "execution_time": round(execution_time, 2)}]])
return response
Wenn Sie eine interne Tabelle generieren, auf die über eine Vorlage oder einen Code zugegriffen werden muss, können Sie entweder einen konstanten Tabellennamen verwenden oder die Tabelle dynamisch benennen und den Namen der Tabelle an den Benutzer zurückgeben, der den Tabellennamen dann an die Ergebnisfunktion weitergibt.
Hier sehen Sie ein Beispiel für eine dynamisch benannte Tabelle, die zum Speichern von Ergebnissen verwendet wird. Der Benutzer macht zwei Aufrufe: einen, um die Daten zu generieren und den Tabellennamen zu erhalten, und einen zweiten, um die Ergebnisse zu sehen.
Die Anbietervorlage ruft die
reach_impression_regression
-UDF auf, um Daten zu verarbeiten (das Präfixcleanroom
zeigt an, dass es sich um eine UDF handelt). Die UDF gibt den Namen des internen Tabellenpräfixes an die Vorlage zurück, die ihn an den Aufrufer zurückgibt.CALL samooha_by_snowflake_local_db.provider.add_custom_sql_template( $cleanroom_name, 'prod_calculate_regression', $$ CALL cleanroom.reach_impression_regression({{ source_table[0] }}, {{ my_table[0] | default('NONE') }}); $$ );
Die Python-UDF gibt den Suffixnamen des Tabellennamens an den Aufrufer der Vorlage zurück.
def main(session, source_table, my_table): ... table = f'results_{suffix}'.upper() retval_df = session.write_pandas(regression_output, table, schema = 'CLEANROOM', auto_create_table = True) return f'Done, results have been written to the following suffix: {suffix}'
Die Anbietervorlage akzeptiert ein übergebenes Tabellennamenssuffix und zeigt den Inhalt dieser Tabelle an.
CALL samooha_by_snowflake_local_db.provider.add_custom_sql_template( $cleanroom_name, 'prod_get_results', $$ SELECT * FROM cleanroom.results_{{ results_suffix | sqlsafe }}; $$ );
Der Verbraucher ruft die Vorlage auf und übergibt dabei das Suffix des Tabellennamens.
CALL samooha_by_snowflake_local_db.consumer.run_analysis( $cleanroom_name, 'prod_get_results', [], [], object_construct( 'results_suffix', $result_suffix -- Table name suffix to identify the results table. ) );
Benutzerdefinierte Funktionen auslösen¶
Benutzerdefinierte Funktionen können entweder über Vorlagen oder über Code (UDFs, UDTFs oder Container-Dienstendpunkte) im Clean Room aufgerufen werden. Auf Funktionen, die von einem beliebigen Teilnehmer hochgeladen wurden, kann von jedem anderen Teilnehmer über Vorlagen oder Code zugegriffen werden.
Clean Room-Funktionen sollten immer in dem entsprechenden Namespace aufgerufen werden:
cleanroom.function_name
beim Aufruf einer benutzerdefinierten UDF/UDTF-Funktionservice_functions.function_name
, wenn Sie eine Funktion aufrufen, die als eingebettete Funktion des Snowpark Container Service angezeigt wird.
Hier finden Sie Beispiele für den Aufruf einer benutzerdefinierten UDF und eines benutzerdefinierten Container-Dienstendpunkts aus einer Vorlage:
Vorlagen verwenden den Bereich cleanroom
, um auf UDF oder UDTFs zuzugreifen.
-- Template to generate results. Calls the UDF 'my_function', which
-- generates a results table inside the clean room called 'results'.
CALL samooha_by_snowflake_local_db.provider.add_custom_sql_template(
$cleanroom_name,
'generate_results_template',
$$
CALL cleanroom.my_function({{ source_table[0] }}, {{ my_table[0] | default('NONE') }});
$$
);
Vorlagen verwenden den Bereich service_functions
für den Zugriff auf Containerdienst-Funktionen.
-- Template to trigger training data generation.
CALL samooha_by_snowflake_local_db.provider.add_custom_sql_template(
$cleanroom_name,
'lal_train',
$$
SELECT service_functions.my_func(
{{ source_table[0] }},
{{ provider_join_col }},
{{ my_table[0] }},
{{ consumer_join_col }},
{{ dimensions | sqlsafe }},
{{ filter_clause }}
) AS train_result;
$$
Häufige Muster für Abläufe mit mehreren Schritten¶
Das Snowpark-API-Beispiel verarbeitet Daten, generiert Zwischentabellen und dann eine Ergebnistabelle mit einem Vorlagenaufruf und gibt die Ergebnisse dann direkt über einen zweiten Vorlagenaufruf aus.
Das Snowpark Container Services-Beispiel erstellt Trainingsdaten mit einem Vorlagenaufruf und speichert die Trainingsdaten in einer internen Tabelle. Eine zweite Vorlage analysiert die Eingaben des Benutzers anhand der gespeicherten Trainingsdaten.