Snowpark Migration Accelerator : Conversion des notebooks¶
Passons au Notebook de rapports dans notre base de code : Notebook de rapports de base - SqlServer Spark.ipynb. Nous allons suivre un ensemble d’étapes similaire à celui que nous avons suivi pour le script du pipeline.
Résoudre tous les problèmes : « Problèmes » signifie ici les problèmes générés par SMA. Jetez un coup d’œil au code de sortie. Résolvez les erreurs d’analyse et les erreurs de conversion, et enquêtez sur les avertissements.
Résoudre les appels de session : La façon dont l’appel de session est écrit dans le code de sortie dépend de l’endroit où nous allons exécuter le fichier. Nous allons résoudre ce problème pour exécuter le(s) fichier(s) de code au même emplacement que celui qui devait être exécuté à l’origine, puis pour les exécuter dans Snowflake.
Résoudre l’entrée/les sorties : Les connexions à différentes sources ne peuvent pas être résolues entièrement par SMA. Il existe des différences entre les plateformes, ce que SMA ignorera généralement. Cela dépend également de l’endroit où le fichier sera exécuté.
Nettoyer et tester ! Exécutons le code. Vérifions qu’il fonctionne. Nous procéderons à des smoke tests dans cet atelier, mais il existe des outils pour effectuer des tests et une validation des données plus étendus, dont des points de contrôle Snowpark Python.
C’est parti !
Résoudre tous les problèmes¶
Commençons à examiner les problèmes présents dans le notebook.
(Notez que vous pouvez ouvrir le notebook dans VS Code, mais pour le visualiser correctement, nous vous conseillons d’installer l’extension Jupyter pour VS Code. Vous pouvez également ouvrir le notebook dans Jupyter, mais Snowflake recommande quand même VS Code avec l’extension Snowflake installée).
Vous pouvez utiliser la fonctionnalité de comparaison pour visualiser les deux à la fois comme nous l’avons fait avec le fichier du pipeline. Dans ce cas, il ressemblera plutôt à un json :

Remarquez qu’il n’y a que deux EWI uniques dans ce notebook. Vous pouvez revenir à la barre de recherche pour les trouver, mais comme cela est très court, vous pouvez aussi simplement… faire défiler l’écran vers le bas. Voici les problèmes uniques :
SPRKPY1002 => _pyspark.sql.readwriter.DataFrameReader.jdbc n’est pas pris en charge. C’est un problème similaire à celui que nous avons vu dans le fichier du pipeline, mais il s’agissait d’un appel en écriture. Il s’agit ici d’un appel en lecture vers la base de données du serveur SQL. Nous allons résoudre ce problème dans un moment.
SPRKPY1068 => « pyspark.sql.dataframe.DataFrame.toPandas n’est pas pris en charge s’il y a des colonnes de type ArrayType, mais il existe une solution de contournement. Voir la documentation pour plus d’informations. Il s’agit d’un autre avertissement. Si nous transmettons un tableau à cette fonction dans Snowpark, cela peut ne pas fonctionner. Gardons cela en tête lorsque nous le testons.
Et c’est tout pour le notebook… et nos problèmes. Nous avons résolu une erreur d’analyse, reconnu que nous devions corriger l’entrée/les sorties, et noté qu’il existe quelques différences fonctionnelles potentielles sur lesquelles nous devons garder un œil. Passons à l’étape suivante : résoudre les appels de session.
Résoudre les appels de session¶
Pour mettre à jour les appels de session dans le notebook de rapports, nous devons localiser la cellule contenant l’appel de session. Cela ressemble à ceci :

Essayons maintenant de faire ce que nous avons déjà fait pour notre fichier de pipeline :
Remplacer toutes les références à la variable de session « spark » par « session » (notez que cette opération est à effectuer dans l’ensemble du notebook).
Supprimez la fonction de configuration avec le pilote spark.
L’avant et l’après de cette opération ressembleront à ceci :
# Old Session
spark = Session.builder.config('spark.driver.extraClassPath', driver_path).app_name("AdventureWorksSummary", True).getOrCreate()
spark.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":7,"minor":4,"patch":10},"attributes":{"language":"Python"}})
# New Session
# Session
session = Session.builder.app_name("AdventureWorksSummary", True).getOrCreate()
session.update_query_tag({"origin":"sf_sit","name":"sma","version":{"major":7,"minor":4,"patch":10},"attributes":{"language":"Python"}})
Notez qu’il y a un autre code dans cette cellule. Ce code :
url = sql_server_url
properties = {'user' : sql_server_user, 'password' : sql_server_password}
# Spark dataframe.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.jdbc is not supported
df = session.read.jdbc(url = url, table = 'dbo.DimCustomer', properties = properties)
print('Session successfully setup.')
Nous sommes presque prêts à nous attaquer à l’instruction de lecture, mais nous n’y sommes pas encore. Déplaçons simplement tout cela vers une autre cellule. Créons une nouvelle cellule sous celle-ci, et déplaçons ce code vers cette cellule. Comme ceci :

Est-ce tout ce dont nous avons besoin pour l’appel de session ? Non. Rappelez-vous (et éventuellement consultez à nouveau) la page précédente dans Remarques sur les appels de session. Vous devrez soit vous assurer que votre fichier connection.toml contient vos informations de connexion, soit spécifier explicitement les paramètres de connexion que vous avez l’intention d’utiliser dans la session.
Résolution des entrées/sorties¶
Résolvons maintenant nos entrées et sorties. Notez que cela peut varier selon que vous exécutez les fichiers localement ou dans Snowflake, mais pour le notebook, tout peut être exécuté localement ou dans Snowflake. Le code sera un peu plus simple, car nous n’aurons même pas besoin d’appeler une session. Nous allons simplement… activer la session. Comme pour le fichier pipeline, nous effectuerons cette opération en deux parties : avec une exécution/orchestration en local, et une exécution dans Snowflake.
La gestion des entrées et des sorties dans le notebook de rapports sera considérablement plus simple que pour le pipeline. Il n’y a pas de lecture à partir d’un fichier local ni de déplacement de données entre des fichiers. Il y a simplement une lecture depuis une table dans le serveur SQL qui est maintenant une lecture depuis une table dans Snowflake. Comme nous n’accéderons pas au serveur SQL, nous pouvons abandonner toute référence aux propriétés du serveur SQL. Et l’instruction de lecture peut être remplacée par une instruction de table dans Snowflake. L’avant et l’après pour cette cellule devraient ressembler à ceci :
# Before
url = sql_server_url
properties = {'user' : sql_server_user, 'password' : sql_server_password}
# Spark dataframe.
#EWI: SPRKPY1002 => pyspark.sql.readwriter.DataFrameReader.jdbc is not supported
df = session.read.jdbc(url = url, table = 'dbo.DimCustomer', properties = properties)
print('Session successfully setup.')
# After
# New table call
# Snowpark Dataframe table.
df = session.table('ADVENTUREWORKS.DBO.DIMCUSTOMER')
print('Table loaded successfully.')
df.show()

Et en fait… c’est tout. Passons à la partie Nettoyer et tester le fichier notebook.
Nettoyer et tester¶
Procédons au nettoyage (comme nous l’avons fait précédemment pour le fichier du pipeline). Nous n’avons jamais examiné nos appels d’importation et nous avons des fichiers de configuration qui ne sont absolument pas nécessaires. Commençons par supprimer les références aux fichiers de configuration. Il s’agira de chacune des cellules comprises entre les instructions d’importation et l’appel de session.#x20;

Examinons maintenant nos importations. La référence à l’Os peut être supprimée. (Il semble que cela n’ait pas non plus été utilisé dans le fichier d’origine). Il existe une référence aux pandas. Les Pandas ne semblent plus être utilisés dans ce notebook maintenant que les fichiers de configuration sont référencés. Il existe une référence à toPandas dans le cadre de l’API du dataframe Snowpark dans la section des rapports, mais cela ne fait pas partie de la bibliothèque des pandas.
Vous pouvez éventuellement remplacer tous les appels d’importation aux pandas par la bibliothèque de pandas modin. Cette bibliothèque optimisera les dataframes pandas pour tirer parti de la puissance de calcul de Snowflake. Ce changement ressemblerait à ceci :
# Old
import pandas as pd
# New
import modin.pandas as pd
import snowflake.snowpark.modin.plugin
Ceci étant dit, nous pouvons aussi le supprimer. Notez que SMA a remplacé toutes les instructions d’importation spécifiques à Spark par celles liées à Snowpark. La cellule d’importation finale ressemblerait à ceci :

Et c’est tout pour notre nettoyage. Nous avons encore quelques EWIs dans les cellules de rapport et de visualisation, mais nous devrions y arriver. Exécutons celui-ci et voyons si nous obtenons une sortie.#x20;

Et c’est fait. Les rapports semblent correspondre à la sortie du notebook Spark. Même si les cellules de rapports semblaient complexes, Snowpark est en mesure de les utiliser. SMA nous fait savoir qu’il pourrait y avoir un problème, mais qu’il semble n’y en avoir aucun. Davantage de tests seraient utiles, mais notre première série de smoke tests a réussi.
Regardons maintenant ce notebook dans Snowsight. Contrairement au fichier du pipeline, nous pouvons le faire entièrement dans Snowsight.
Exécution du notebook dans Snowsight¶
Prenons la version du notebook que nous avons actuellement (après avoir traité les problèmes, les appels de session et les entrées et sorties) et chargeons-la dans Snowflake. Pour ce faire, accédons à la section Notebooks dans SnowSight :

Sélectionnez la flèche vers le bas à côté du bouton +Notebook en haut à droite, puis sélectionnez « Importer un fichier .ipynb » (illustré ci-dessus).#x20;
Une fois ce fichier importé, choisissez le fichier de notebook avec lequel nous travaillons dans le répertoire de sortie créé par SMA dans le dossier de votre projet.
Une boîte de dialogue de création de notebook s’ouvre. Pour ce chargement, nous choisirons les options suivantes :
Emplacement du notebook :
Base de données : ADVENTUREWORKS
Schéma : DBO
Environnement Python : Exécuter sur un entrepôt
Ce n’est pas un grand notebook avec un tas de ml. Il s’agit d’un notebook de rapports de base. Nous pouvons l’exécuter sur un entrepôt.#x20;
Entrepôt de requêtes : DEFAULT_WH
Entrepôt du notebook : DEFAULT_WH (vous pouvez le laisser comme entrepôt choisi par le système (sera un entrepôt Streamlit)… pour ce notebook, cela n’aura pas d’importance)
Vous pouvez voir ces sélections ci-dessous :

Cela devrait charger votre notebook dans Snowflake et cela ressemblera à ceci :

Il y a quelques contrôles/modifications rapides que nous devons apporter à partir de la version que nous venez de tester localement afin de nous assurer que le notebook fonctionne dans Snowsight :
Modifier les appels de session pour récupérer la session active
Assurez-vous que les bibliothèques dépendantes que nous devons installer sont disponibles
Commençons par la première. Il peut sembler inhabituel de modifier à nouveau l’appel de session après avoir passé beaucoup de temps dessus, mais nous exécutons les opérations à l’intérieur de Snowflake à présent. Vous pouvez supprimer tout ce qui est associé à la lecture de l’appel de session et le remplacer par l’appel « get_active_session » qui est standard en haut de la plupart des notebooks Snowflake :
//# Old for Jupyter
session = Session.builder.app_name("AdventureWorksSummary", True).getOrCreate()
# New for Snowsight
from snowflake.snowpark.context import get_active_session
session = get_active_session()
Nous n’avons pas besoin de spécifier des paramètres de connexion ou de mettre à jour un fichier .toml car nous sommes déjà connectés et nous sommes dans Snowflake.
Remplaçons l’ancien code de la cellule par le nouveau code. Cela ressemblera à ceci :

Occupons-nous maintenant des paquets disponibles pour cette exécution, mais au lieu de déterminer ce que nous devons ajouter, laissons Snowflake le faire. L’une des meilleures parties de l’utilisation d’un notebook est que nous pouvons exécuter des cellules individuelles et voir ce que sont les résultats. Exécutons notre cellule de bibliothèque d’importation.
Si vous ne l’avez pas encore fait, démarrez la session en cliquant dans le coin supérieur droit de l’écran sur « Démarrer » :

Si vous exécutez la cellule la plus élevée du notebook, vous découvrirez probablement que matplotlib n’est pas chargé dans la session :

C’est un point assez important pour ce notebook. Vous pouvez ajouter cette bibliothèque à votre notebook/session en utilisant l’option « Paquets » en haut à droite du notebook :

Recherchez matplotlib et sélectionnez-le. Ce paquet sera alors disponible dans la session.

Une fois que vous avez chargé cette bibliothèque, vous devrez redémarrer la session. Une fois que vous avez redémarré la session, exécutez à nouveau cette première cellule. Vous recevrez certainement un message disant que l’opération a réussi cette fois-ci.

Une fois les paquets chargés, la session réparée et le reste des problèmes dans le code déjà résolus, que pouvons-nous faire pour vérifier le reste du notebook ? L’exécuter ! Vous pouvez exécuter toutes les cellules du notebook en sélectionnant « Exécuter tout » dans le coin supérieur droit de l’écran, et voir si nous obtenons des erreurs.
Il semble que l’exécution a réussi :

Si vous comparez l’exécution des deux notebooks, la seule différence est que la version de Snowflake place tous les ensembles de données de sortie en premier suivis des images, alors qu’ils sont mélangés dans le notebook Spark Jupyter :

Notez que cette différence n’est pas une différence d’API, mais plutôt une différence dans la façon dont les notebooks dans Snowflake orchestrent tout ceci. Il s’agit probablement d’une différence qu’AdventureWorks est prêt à accepter !
Conclusions¶
En utilisant SMA, nous avons pu accélérer la migration à la fois d’un pipeline de données et d’un notebook de rapports. Plus vous en avez, plus un outil comme SMA peut fournir de la valeur.
Et revenons au flux d’évaluation -> conversion -> validation auquel nous revenons toujours. Dans cette migration, nous avons :
Configuré le projet dans SMA
Exécuté le moteur d’évaluation et de conversion de SMA sur les fichiers de code
Examiné les rapports de sortie de SMA pour mieux comprendre ce que nous avons
Vérifié ce qui n’a pas pu être converti par SMA dans VS Code
Résolu les problèmes et les erreurs
Résolu les références de session
Résolu les références aux entrées/sorties
Exécuté le code localement
Et exécuté le code dans Snowflake
Exécuté les scripts qui venaient d’être migrés et validé leur réussite
Snowflake a consacré beaucoup de temps à améliorer ses capacités d’ingestion et d’ingénierie des données, tout comme il a consacré du temps à améliorer les outils de migration tels que SnowConvert, l’Assistant de migration SnowConvert et Snowpark Migration Accelerator. Chacun de ces éléments continuera à s’améliorer. N’hésitez pas à contacter Snowflake si vous avez des suggestions concernant les outils de migration. Les équipes Snowflake sont toujours à la recherche de commentaires supplémentaires pour améliorer les outils.