Code-Bundles

Jeder Teilnehmende kann kundenspezifische Python-Prozeduren, UDFs oder UDTFs mit Vorlagen für die Zusammenarbeit bündeln. Vorlagen wiederum verweisen auf den gebündelten Code, um komplexe Datenaktionen in der Zusammenarbeit auszuführen. Zu den üblichen Verwendungszwecken gehören maschinelles Lernen oder die angepasste Datenmanipulation innerhalb einer Abfrage. Ihr hochgeladener Code kann Pakete aus einem genehmigten Bundle von Python-Paketen und der Snowpark-API importieren und verwenden.

Kundenspezifischer Code kann nur über Vorlagen und nicht direkt aufgerufen werden.

Bemerkung

Python ist die einzige Codierungssprache, die Code-Bundles unterstützt.

Die folgenden Abschnitte zeigen, wie Sie Code-Bundles hochladen und verwenden.

Implementieren von kundenspezifischen Code-Bundles

So laden Sie ein Code-Bundle hoch und verwenden es:

Der Codeüberstellende:

  1. Erstellt und registriert den Code durch Aufrufen von:ref:REGISTER_CODE_SPEC<label-dcr_collab_register_code_spec>.

    Der Code kann inline in der Spezifikation eingebettet sein oder über einen Stagingbereich verknüpft werden.

  2. Erstellt eine Vorlage mit Verweis auf die Code-Bundle-Spezifikation anhand der ID im code_specs-Array der Vorlage. Fügen Sie dieses Feld als Peer der Felder „Vorlage“ und „Parameter“ hinzu, wie im folgenden Beispiel gezeigt:

     parameters:
       - name: <parameter_name>
         description: <parameter_description>
         required: <true_or_false>
         default: <default_value>
         type: <data_type>
    
     code_specs:             # Optional: List of code bundles used by this template
     - <code_spec_id>        # One or more code spec IDs.
    
     template: |
       <template_content>
    
  3. Registriert die Vorlage und verknüpft die Vorlage dann mit der Zusammenarbeit.

Der Analyseausführende:

  • Führt die Vorlage aus, indem er RUN als Standardmethode aufruft.

Wichtig

Snowflake führt Sicherheitsprüfungen für alle hochgeladenen Bundles durch, bevor sie in einem Clean Room eingesetzt werden. Wenn eine Sicherheitsprüfung fehlschlägt, werden die Vorlage und der gebündelte Code nicht bereitgestellt und stehen nicht zur Verfügung.

Um zu bestätigen, dass eine Vorlage mit einem Code-Bundle bereitgestellt und einsatzbereit ist, führen Sie die folgenden Schritte aus:

  1. Suchen Sie den Namen der Clean Room-Anwendung, in der Sie versuchen, das Code-Bundle bereitzustellen:

    SHOW APPLICATIONS LIKE 'SFDCR_<collaboration name>';
    
  2. Überprüfen Sie den Wert für upgrade_state in der DESCRIBE APPLICATION-Antwort. Wenn der Upgrade-Status COMPLETE lautet, wurden die Sicherheitsprüfungen bestanden und die neue Vorlage und das Bundle können verwendet werden. Übergeben Sie den Anwendungsnamen, der vom Befehl im vorherigen Schritt zurückgegeben wurde, mit SQL wie im folgenden Beispiel: SQL-Code:

    DESCRIBE APPLICATION <application name>
    

Erstellen und Registrieren der Code-Bundle-Spezifikation

Der erste Schritt beim Hochladen von kundenspezifischem Code besteht darin, die Code-Bundle-Spezifikation zu erstellen und zu registrieren.

Benutzerdefinierte Funktionen werden in einer YAML-Code-Bundle-Spezifikation definiert. Jedes Code-Bundle stellt eine oder mehrere Funktionen zur Verfügung, die von einer Vorlage aufgerufen werden können. Die Code-Bundle-Spezifikation kann entweder den Code inline in der Spezifikation enthalten oder mit Code in einem Snowflake-Stagingbereich verknüpft sein.

Ein Teilnehmender registriert eine Spezifikation durch den Aufruf von REGISTRY.REGISTER_CODE_SPEC, wodurch die Bundle-ID zurückgegeben wird.

Nachdem die Vorlage, die auf das Code-Bundle verweist, mit der Zusammenarbeit verknüpft wurde, ist dieses Code-Bundle für jeden in der Zusammenarbeit sichtbar, der auf eine Vorlage zugreifen kann, die das Code-Bundle verknüpft. Rufen Sie VIEW_CODE_SPECS auf, um zugängliche Code-Bundles in einer Zusammenarbeit aufzulisten.

Jede Person, die ein Code-Bundle in einer Zusammenarbeit sehen kann, kann es in ihren eigenen Vorlagen in dieser Zusammenarbeit sehen und verwenden. Jeder Inline-Code kann von jedem Mitglied der Zusammenarbeit angezeigt werden, aber Stagingbereich-Artefaktcode kann nicht von Teilnehmenden angezeigt werden. Teilnehmende müssen sicherstellen, dass der content_hash der referenzierten Artefakte mit der Überprüfung der Codeintegrität übereinstimmt.

Die folgende Code-Bundle-Spezifikation stellt eine einzelne Python-UDF namens normalize_value zur Verfügung, wodurch die normalize-Funktion aufgerufen wird, die in dieser Spezifikation definiert ist:

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_CODE_SPEC(
  $$
  api_version: 2.0.0
  spec_type: code_spec
  name: custom_udf
  version: v1
  functions:
    - name: normalize_value
      type: UDF
      language: PYTHON
      handler: normalize
      arguments:
        - name: value
          type: FLOAT
      returns: FLOAT
      code_body: |
        def normalize(value):
            return value / 100.0
  $$
);

Erstellen und Registrieren der aufrufenden Vorlage

Nachdem die Codespezifikation registriert wurde, registriert der Teilnehmende dann eine Vorlage, die dieses Code-Bundle verwendet. Um ein Code-Bundle zu verwenden, fügen Sie die ID der Bundle-Spezifikation in das Feld code_specs der Vorlage ein. Wenn Sie diese Vorlage zur Zusammenarbeit hinzufügen, wird auch der Code gebündelt, um in der Zusammenarbeit verfügbar zu sein.

Eine Vorlage ruft eine benutzerdefinierte Funktion mit der Syntax cleanroom.spec_name$function_name auf. Beachten Sie die Literale . und``$`` zur Namensbereichskennzeichnung.

Bemerkung

Verwenden Sie den Namen der Spezifikation, nicht die Spezifikations-ID, um auf eine Funktion in Ihrer Vorlage zu verweisen. So können Sie die Version Ihres Code-Bundles schnell aktualisieren, ohne alle Verweise darauf in Ihrer Vorlage ändern zu müssen.

Im folgenden Beispiel verwendet eine Vorlage die Funktion normalize_value aus dem Code-Bundle custom_udf:

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
  $$
  api_version: 2.0.0
  spec_type: template
  name: normalization_template
  version: v1
  type: sql_analysis
  code_specs:
    - custom_udf_v1  -- Imports the code bundle.
  template: |
    SELECT cleanroom.custom_udf$normalize_value(100)  -- Calls the UDF.
      AS normalized
        FROM {{ source_tables[0] }}
  $$
);

Hinzufügen einer Vorlage zu einer Zusammenarbeit

Fügen Sie die Vorlage, die Ihre Funktion aufruft, auf die standardmäßige Weise zur Zusammenarbeit hinzu. Weitere Informationen dazu finden Sie unter Vorlagen.

Snowflake validiert und lädt die Daten in die Zusammenarbeit hoch, wenn die aufrufende Vorlage zu einer Zusammenarbeit hinzugefügt wird. Das folgende Beispiel zeigt eine Anforderung zum Hinzufügen einer Vorlage zu einer bestehenden Zusammenarbeit:

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.COLLABORATION.ADD_TEMPLATE_REQUEST(
  'my_collaboration',
  'normalization_template_v1',
  ['consumer']
);

Bemerkung

Die Installation einer Vorlage mit einem Code-Bundle löst eine Snowflake-Sicherheitsüberprüfung aus und gibt einen neuen Patch des zugrunde liegenden Clean Rooms aus. Die Vorlage wird erst verfügbar oder verwendbar, wenn der Prozess abgeschlossen ist und der Patch installiert wurde.

So überprüfen Sie den Fortschritt der Patchinstallation:

  1. Suchen Sie den Namen der Clean Room-Anwendung. In der Regel ist dies SFDCR_<clean room name>, aber Sie können suchen, um sicher zu sein:

    -- Find the exact name of the clean room application.
    SHOW APPLICATIONS LIKE 'SFDCR_%';
    
  2. Überprüfen Sie den Status der Patchinstallation. Warten Sie, bis upgrade_state in der folgenden Abfrage den Status COMPLETE aufweist:

    DESCRIBE APPLICATION SFDCR_<application name>;
    

Versionierung Ihres Codes

Jede registrierte Codespezifikation muss einen eindeutigen Namen + Version für alle Registrys in Ihrem Konto haben. Eine Vorlage lädt einen bestimmten Namen und eine Version einer Codespezifikation. Wenn Sie eine neue Version Ihres Codes erstellen oder verwenden möchten, müssen Sie eine neue Version der Vorlage übermitteln, die im Feld „code_specs“ auf die neue Codeversion verweist. Sie müssen den Textteil der Vorlage nicht ändern. Beispiel:

Schritt 1: Verwenden Sie Version 1 des Code-Bundles:

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
  $$
  api_version: 2.0.0
  spec_type: template
  name: normalization_template
  version: v1
  type: sql_analysis
  code_specs:
    - custom_udf_v1  -- Bundle ID includes the version number.
  template: |
    SELECT cleanroom.custom_udf$normalize_value(100)  -- Calls the UDF.
      AS normalized
        FROM {{ source_tables[0] }}
  $$
);

Schritt 2: Aktualisieren und registrieren Sie die neue Version Ihres Code-Bundles und aktualisieren Sie dann Ihre Vorlage, um die neue Version zu verwenden:

CALL SAMOOHA_BY_SNOWFLAKE_LOCAL_DB.REGISTRY.REGISTER_TEMPLATE(
  $$
  api_version: 2.0.0
  spec_type: template
  name: normalization_template
  version: v2        -- Update the template version.
  type: sql_analysis
  code_specs:
    - custom_udf_v2  -- Use the new code bundle.
  template: |
    SELECT cleanroom.custom_udf$normalize_value(100)  -- No change needed here.
      AS normalized
        FROM {{ source_tables[0] }}
  $$
);

Beachten Sie, dass Funktionsnamen nicht die Version enthalten, sodass Sie den aufrufenden Code im Vorlagentext nicht ändern müssen, wenn Sie eine neue Version einer Funktion hochladen.

Beispielspezifikationen

Inline-UDF mit Codetext

Eine einfache UDF mit Inline-Python-Code:

api_version: 2.0.0
spec_type: code_spec
name: string_utils
version: v1
description: String utility functions

functions:
  - name: clean_string
    type: UDF
    language: PYTHON
    runtime_version: "3.10"
    handler: clean
    arguments:
      - name: input_str
        type: STRING
    returns: STRING
    description: Removes leading/trailing whitespace and converts to lowercase
    code_body: |
      def clean(input_str):
          if input_str is None:
              return None
          return input_str.strip().lower()

  - name: extract_domain
    type: UDF
    language: PYTHON
    runtime_version: "3.10"
    handler: extract
    arguments:
      - name: email
        type: STRING
    returns: STRING
    description: Extracts domain from email address
    code_body: |
      def extract(email):
          if email is None or '@' not in email:
              return None
          return email.split('@')[1]

UDTF (Benutzerdefinierte Tabellenfunktionen)

Dieses Beispiel-YAML definiert eine UDTF, die mehrere Zeilen zurückgibt:

api_version: 2.0.0
spec_type: code_spec
name: tokenizer
version: v1
description: Text tokenization UDTF

functions:
  - name: tokenize_text
    type: UDTF
    language: PYTHON
    runtime_version: "3.10"
    handler: Tokenizer
    arguments:
      - name: text
        type: STRING
      - name: delimiter
        type: STRING
    returns: TABLE(token STRING, position INTEGER)
    description: Splits text into tokens and returns each with its position
    code_body: |
      class Tokenizer:
          def process(self, text, delimiter):
              if text is None:
                  return
              tokens = text.split(delimiter if delimiter else ' ')
              for i, token in enumerate(tokens):
                  yield (token.strip(), i)

Staging-Artefakt mit Wheel-Paket

Lesen Sie unbedingt die Anforderungen an die Dokumentation von stage_path zur Verknüpfung mit Stagingcode in Ihrer Codespezifikation.

Dieses Beispiel-YAML verwendet ein Staging-Python-Wheel-Paket:

api_version: 2.0.0
spec_type: code_spec
name: ml_scoring
version: v2
description: ML scoring functions using custom library

artifacts:
  - alias: ml_lib
    stage_path: "@MY_DB.PUBLIC.CODE_STAGE/libs/ml_scoring_lib-1.0.0-py3-none-any.whl"
    description: Custom ML scoring library
    content_hash: "a1b2c3d4e5f6..."

functions:
  - name: predict_score
    type: UDF
    language: PYTHON
    runtime_version: "3.10"
    handler: ml_scoring_lib.predictor.predict
    arguments:
      - name: features
        type: ARRAY
    returns: FLOAT
    packages:
      - numpy
      - scikit-learn
    imports:
      - ml_lib
    description: Predicts score using trained ML model

Gespeicherte Prozeduren

Dieses Beispiel-YAML definiert eine gespeicherte Prozedur für die Datenverarbeitung:

api_version: 2.0.0
spec_type: code_spec
name: data_processor
version: v1
description: Data processing procedures

procedures:
  - name: aggregate_metrics
    language: PYTHON
    runtime_version: "3.10"
    handler: process
    arguments:
      - name: table_name
        type: STRING
      - name: group_column
        type: STRING
    returns: STRING
    packages:
      - snowflake-snowpark-python
    description: Aggregates metrics by specified column
    code_body: |
      def process(session, table_name, group_column):
          df = session.table(table_name)
          result = df.group_by(group_column).count()
          result.write.mode("overwrite").save_as_table("aggregated_results")
          return f"Aggregated {df.count()} rows into aggregated_results"

Mehrere Python-Dateien als Staging-Artefakte

Lesen Sie unbedingt die Anforderungen an die Dokumentation von stage_path zur Verknüpfung mit Stagingcode in Ihrer Codespezifikation.

Dieses Beispiel-YAML verwendet mehrere Python-Quelldateien in einem Stagingbereich:

api_version: 2.0.0
spec_type: code_spec
name: analytics_suite
version: v3
description: Analytics suite with multiple modules

artifacts:
  - alias: utils
    stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/utils.py"
    description: Utility functions
  - alias: transformers
    stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/transformers.py"
    description: Data transformation functions
  - alias: validators
    stage_path: "@MY_DB.PUBLIC.CODE_STAGE/analytics/validators.py"
    description: Validation functions

functions:
  - name: transform_and_validate
    type: UDF
    language: PYTHON
    runtime_version: "3.10"
    handler: transformers.transform_validate
    arguments:
      - name: data
        type: OBJECT
    returns: OBJECT
    imports:
      - utils
      - transformers
      - validators
    description: Transforms and validates input data