Snowpark Container Services : exécution SQL¶
Votre conteneur d’application peut se connecter à Snowflake et exécuter SQL. Cette rubrique décrit comment le code du conteneur obtient les informations requises pour se connecter à Snowflake, y compris les identifiants de connexion d’authentification, la base de données et le contexte du schéma du service, ainsi que l’entrepôt utilisé pour exécuter les SQL Instructions.
Options de configuration des identifiants¶
Snowflake recommande que les conteneurs d’application utilisent des identifiants de connexion fournis par Snowflake pour s’authentifier auprès de Snowflake lors de l’exécution de SQL. Bien qu’il soit possible d’utiliser d’autres identifiants de connexion en se connectant via une intégration d’accès externe (EAI), la connexion via une EAI traite le service comme s’il fonctionnait en dehors de Snowflake et se connecte à Snowflake via Internet.
Vous avez trois options pour vous connecter à Snowflake à partir d’un conteneur de service :
Utiliser les informations d’identification de l’utilisateur du service fournies par Snowflake : Snowflake fournit chaque service avec des identifiants de connexion, qui sont appelés identifiants de connexion de service. Un service utilise ces identifiants de connexion pour se connecter à Snowflake en tant qu’utilisateur du service.
Utiliser les identifiants de connexion de l’appelant fournis par Snowflake (droits de l’appelant) : lorsque vous configurez votre service avec les droits de l’appelant, Snowflake fournit également des identifiants de connexion pour que le service puisse se connecter à Snowflake en tant qu’utilisateur appelant.
Utiliser d’autres identifiants de connexion : dans ce cas, vous utilisez une intégration d’accès externe (EAI) qui permet à votre service de se connecter au point de terminaison Internet de Snowflake en utilisant des identifiants de connexion valides. Cette option nécessite un administrateur pour créer le fichier d’EAI, puis accordez le privilège USAGE sur l’intégration au rôle de propriétaire de service.
Note
Si vous utilisez des intégrations d’accès externes pour accéder à Snowflake, vous pourriez envoyer des informations potentiellement sensibles sur Internet.
Pour des exemples de code qui utilisent divers pilotes Snowflake pour la connexion à Snowflake, voir Exemples de connexion Snowflake.
Utilisation des identifiants de connexion de l’utilisateur du service fournis par Snowflake¶
Lorsque vous utilisez des identifiants de connexion de service fournis par Snowflake, tenez compte des effets suivants :
Chaque objet dans Snowflake possède un rôle propriétaire, qui est le rôle utilisé pour créer l’objet. Le rôle de propriétaire d’un service détermine les capacités auxquelles le service est autorisé lorsqu’il interagit avec Snowflake. Ces capacités comprennent l’exécution SQL, l’accès aux zones de préparation et le fonctionnement réseau de service à service.
Lorsque vous créez un service, Snowflake crée également un utilisateur de service spécifique à ce service. Cet utilisateur de service n’a accès qu’à deux rôles : le rôle de propriétaire du service et le rôle « PUBLIC ». Le rôle par défaut de l’utilisateur de service est le rôle de propriétaire de service.
Lorsque vous démarrez un service, y compris des services de tâche, Snowflake effectue plusieurs actions. Dans chacun de vos conteneurs d’application, Snowflake permet au code du conteneur d’utiliser des pilotes pour se connecter à Snowflake et exécuter SQL, ce qui est similaire à tout autre code sur votre ordinateur se connectant à Snowflake. La liste suivante montre les actions que Snowflake effectue lorsque vous démarrez un service :
Fournit des informations d’identification (un jeton OAuth) dans le conteneur dans un fichier qui est nommé
/snowflake/session/token. Le code du conteneur utilise ces identifiants de connexion pour s’authentifier en tant qu’utilisateur du service. Ce jeton OAuth ne peut pas être utilisé en dehors de Snowpark Container ServicesSnowflake définit les variables d’environnement suivantes pour vous permettre de configurer un client Snowflake dans votre code de service :
SNOWFLAKE_ACCOUNT : Cette variable définie sur le localisateur de compte du compte Snowflake sous lequel le service est actuellement exécuté.
SNOWFLAKE_HOST : Cette variable fournit le nom d’hôte qui est utilisé pour se connecter à Snowflake.
Lorsque vous créez une connexion à Snowflake en tant qu’utilisateur de service, le code du conteneur doit utiliser SNOWFLAKE_HOST, SNOWFLAKE_ACCOUNT et le jeton OAuth. Le jeton OAuth ne peut pas être utilisé sans utiliser également SNOWFLAKE_HOST.
Exemple
Dans Tutoriel 2 (voir main.py), le code lit les variables d’environnement comme indiqué dans l’exemple suivant :
SNOWFLAKE_ACCOUNT = os.getenv('SNOWFLAKE_ACCOUNT')
SNOWFLAKE_HOST = os.getenv('SNOWFLAKE_HOST')
Le code transmet ces variables à un code de création de connexion pour le client Snowflake choisi. Le conteneur utilise ces identifiants de connexion pour créer une nouvelle session, avec le rôle de propriétaire du service comme rôle principal, afin d’exécuter des requêtes. L’exemple suivant est le code minimum requis pour créer une connexion Snowflake en Python :
def get_login_token():
with open('/snowflake/session/token', 'r') as f:
return f.read()
conn = snowflake.connector.connect(
host = os.getenv('SNOWFLAKE_HOST'),
account = os.getenv('SNOWFLAKE_ACCOUNT'),
token = get_login_token(),
authenticator = 'oauth'
)
Notez les détails suivants concernant ce jeton OAuth :
Snowflake actualise le contenu du fichier
/snowflake/session/tokentoutes les quelques minutes. Chaque jeton d’accès est valable pendant une heure maximum. Une fois qu’un conteneur s’est connecté avec succès à Snowflake, le délai d’expiration ne s’applique pas à la connexion, comme c’est le cas pour les sessions créées directement par les utilisateurs.Ce jeton OAuth n’est valable que pour le service Snowflake concerné. Vous ne pouvez pas copier le jeton OAuth et l’utiliser en dehors du service.
Si vous utilisez le jeton OAuth pour se connecter, une nouvelle session est créée. Le jeton OAuth n’est associé à aucune session SQL existante.
Note
Une différence importante entre l’exécution de procédures stockées et l’exécution d’un service est que les procédures stockées s’exécutent dans la même session que le SQL qui les exécute. Mais chaque fois qu’un conteneur établit une nouvelle connexion, vous créez une nouvelle session.
Pour voir les requêtes émises par un utilisateur de service spécifique, vous pouvez utiliser le rôle ACCOUNTADMIN pour voir l”historique des requêtes. Le nom d’utilisateur de l’utilisateur du service apparaît sous les formes suivantes :
Pour un service créé avant la version du serveur 8.35, le nom d’utilisateur du service est au format
SF$SERVICE$unique-id.Pour un service créé après la version du serveur 8.35, le nom d’utilisateur du service est le même que le nom du service.
Note
Un rôle de propriétaire d’un service fait référence au rôle qui a créé le service. Vous pouvez également définir des rôles de service pour gérer l’accès aux points de terminaison exposés par le service. Pour plus d’informations, voir Gestion des privilèges liés aux services.
À propos de l’utilisation des informations d’identification de l’appelant fournies par Snowflake (droits de l’appelant)¶
Dans certains scénarios d’application, vous pouvez avoir besoin d’exécuter des requêtes en utilisant le contexte de l’utilisateur final plutôt que celui de l’utilisateur du service comme expliqué dans la section précédente. La fonction de droit de l’appelant est utilisée dans ce contexte.
Par exemple, supposons que vous créiez un service qui expose un point de terminaison public pour une application Web qui affiche un tableau de bord utilisant des données stockées dans Snowflake. Vous accordez à d’autres utilisateurs de votre compte Snowflake l’accès au tableau de bord en leur attribuant le rôle de service). Lorsqu’un utilisateur se connecte, le tableau de bord n’affiche que les données auxquelles l’utilisateur est autorisé à accéder.
Cependant, comme les conteneurs exécutent par défaut des requêtes en utilisant l’utilisateur du service et le rôle de propriétaire du service, le tableau de bord affiche les données auxquelles le rôle de propriétaire du service a accès, quel que soit l’utilisateur final connecté au point de terminaison. Par conséquent, le tableau de bord n’est pas limité aux données auxquelles l’utilisateur final est autorisé à accéder, ce qui permet à l’utilisateur connecté de voir les données auxquelles il ne devrait pas avoir accès.
Pour limiter le tableau de bord aux seules données accessibles à l’utilisateur connecté, les conteneurs de l’application doivent exécuter SQL en utilisant les privilèges accordés à l’utilisateur final. Vous pouvez activer cette fonction en utilisant les droits de l’appelant dans l’application.
Note
La fonction des droits de l’appelant n’est prise en charge que lorsque accède à un service en utilisant l’entrée réseau. La fonction n’est pas disponible lors de l’utilisation d’une fonction de service pour accéder au service.
La fonction des droits de l’appelant n’est actuellement pas prise en charge dans une application Snowflake Native App (applications avec les conteneurs).
Configurer les droits de l’appelant pour votre service¶
La configuration des droits de l’appelant pour votre application se fait en deux étapes.
Dans la spécification de service </developer-guide/snowpark-container-services/specification-reference>, définissez ```executeAsCaller` sur
truecomme indiqué dans le fragment de spécification suivant :spec: containers: ... capabilities: securityContext: executeAsCaller: true
Cette configuration indique explicitement à Snowflake que l’application a l’intention d’utiliser les droits de l’appelant et fait en sorte que Snowflake insère l’en-tête
Sf-Context-Current-User-Tokendans chaque requête entrante avant d’envoyer la requête au conteneur de l’application. Ce jeton utilisateur facilite l’exécution de la requête en tant qu’utilisateur appelant. S’il n’est pas spécifié,executeAsCallerdevient par défautfalse.La spécification de l’option
executeAsCallern’affecte pas la possibilité pour le service d’exécuter des requêtes en tant qu’utilisateur du service et le rôle de propriétaire du service. LorsqueexecuteAsCallerest activé, le service a la possibilité de se connecter à Snowflake à la fois en tant qu’utilisateur appelant et en tant qu’utilisateur du service.Pour établir une connexion Snowflake au nom de l’utilisateur appelant, mettez à jour votre code d’application afin de créer un jeton de connexion qui inclut à la fois le jeton OAuth que Snowflake a fourni au service et le jeton utilisateur de l’en-tête
Sf-Context-Current-User-Token.Le jeton de connexion doit respecter ce format :
<service-oauth-token>.<Sf-Context-Current-User-Token>.Cette mise à jour est démontrée dans le fragment de code Python suivant :
# Environment variables below will be automatically populated by Snowflake. SNOWFLAKE_ACCOUNT = os.getenv("SNOWFLAKE_ACCOUNT") SNOWFLAKE_HOST = os.getenv("SNOWFLAKE_HOST") def get_login_token(): with open("/snowflake/session/token", "r") as f: return f.read() def get_connection_params(ingress_user_token = None): # start a Snowflake session as ingress user # (if user token header provided) if ingress_user_token: logger.info("Creating a session on behalf of the current user.") token = get_login_token() + "." + ingress_user_token else: logger.info("Creating a session as the service user.") token = get_login_token() return { "account": SNOWFLAKE_ACCOUNT, "host": SNOWFLAKE_HOST, "authenticator": "oauth", "token": token } def run_query(request, query): ingress_user_token = request.headers.get('Sf-Context-Current-User-Token') # ingress_user_token is None if header not present connection_params = get_connection_params(ingress_user_token) with Session.builder.configs(connection_params).create() as session: # use the session to execute a query.
Dans l’exemple ci-dessus :
La fonction
get_login_tokenlit le fichier dans lequel Snowflake a copié le jeton OAuth pour que le conteneur l’utilise.La fonction
get_connection_paramsconstruit un jeton en concaténant le jeton OAuth et le jeton utilisateur de l’en-têteSf-Context-Current-User-Token. La fonction inclut ce jeton dans un dictionnaire de paramètres que l’application utilise pour se connecter à Snowflake.
Note
Lorsqu’un service utilise les droits de l’appelant, il peut se connecter à Snowflake en tant que plusieurs utilisateurs. Vous êtes responsable de la gestion de l’accès aux ressources qui ne sont pas gérées par Snowflake.
Par exemple, dans les applications Streamlit, l’objet st.connection met automatiquement en cache la connexion à l’aide de st.cache_resource dans l’état global, le rendant accessible dans les sessions Streamlit qui sont lancées par différents utilisateurs. Lorsque vous utilisez les droits de l’appelant, pensez à utiliser st.session_state pour stocker les connexions par session afin d’éviter le partage de connexions entre utilisateurs.
Pour un exemple avec des instructions étape par étape, voir Créer un service avec les droits de l’appelant activés.
Accès à un service dont les droits de l’appelant sont configurés¶
La configuration des droits de l’appelant consiste pour votre service à établir une connexion Snowflake au nom de l’appelant. La manière dont vous vous connectez aux points de terminaison du service (par programmation ou à l’aide d’un navigateur) reste la même. Après la connexion, les comportements et options suivants s’appliquent :
Accès à un point de terminaison public à l’aide d’un navigateur : après vous être connecté à un point de terminaison, le service établit une connexion à Snowflake au nom de l’utilisateur appelant en utilisant le rôle par défaut de l’utilisateur. Si aucun rôle par défaut n’est configuré pour l’utilisateur, le rôle PUBLIC est utilisé.
Accès à un point de terminaison public par programme : lorsque se connecte à un point de terminaison par programme à l’aide du jeton JWT, vous pouvez choisir de définir le paramètre
scopepour spécifier le rôle à activer
Actuellement, après qu’un service a établi la bonne connexion d’un appelant à Snowflake au nom de l’appelant, le changement de rôle n’est pas pris en charge. Si votre application doit utiliser différents rôles pour accéder à différents objets, vous devez changer la propriété des rôles secondaires par défaut de l’utilisateur.
Pour configurer l’utilisateur pour que tous les rôles secondaires soient actifs par défaut, utilisez la commande ALTER USER pour définir la propriété :ref:`DEFAULT_SECONDARY_ROLES <label-create_user_default_secondary_roles>`de l’utilisateur avec (’ALL’), comme le montre l’exemple suivant :
ALTER USER my_user SET DEFAULT_SECONDARY_ROLES = ( 'ALL' );
Gestion de l’accès des appelants à un service¶
Lorsqu’un service crée une session de droits de l’appelant, la session opère en tant qu’utilisateur de l’appelant (et non en tant qu’utilisateur du service). Lorsqu’une opération est effectuée à l’aide de cette session, Snowflake applique deux contrôles d’autorisation successifs :
Le premier contrôle des autorisations s’effectue comme si l’utilisateur créait directement la session. Ce contrôle fait partie des contrôles d’autorisation normaux que Snowflake effectue pour l’utilisateur.
Le deuxième contrôle des autorisations permet de vérifier que le service est autorisé à effectuer l’opération pour le compte d’un utilisateur. Snowflake s’en assure en vérifiant que le rôle de propriétaire du service a reçu les autorisations nécessaires de la part de l’appelant.
Dans une session de droits de l’appelant, le contrôle normal des autorisations et le contrôle des droits de l’appelant du rôle de propriétaire du service <label-spcs_additional_considerations_configuring_callers_rights> doivent tous deux autoriser l’opération ; on parle alors de droits restreints de l’appelant. Par défaut, le service n’a pas l’autorisation de faire quoi que ce soit au nom d’un utilisateur. Vous devez explicitement accorder des droits d’appelant au service afin qu’il puisse fonctionner avec les privilèges de l’appelant.
Par exemple, supposons qu’un utilisateur U1 utilise un rôle R1, qui dispose du privilège SELECT sur la table T1. Lorsque U1 se connecte au point de terminaison public de votre service (example_service), qui est configuré pour utiliser les droits de l’appelant, le service établit alors une connexion avec Snowflake au nom de U1.
Pour permettre au service d’interroger la table de requête T1 pour le compte de U1, vous devez accorder au rôle de propriétaire du service les privilèges suivants :
Privilèges pour résoudre le nom de la table, en accordant une autorisation à l’appelant qui permet au service de s’exécuter avec le privilège USAGE sur la base de données et le schéma de cette table.
Privilèges permettant d’utiliser un entrepôt pour exécuter des requêtes en accordant une autorisation à l’appelant qui permet au service de s’exécuter avec le privilège USAGE sur un entrepôt.
Privilèges pour interroger la table en accordant une autorisation à l’appelant qui permet au service de s’exécuter avec le privilège SELECT sur la table
T1.
L’exemple suivant montre comment accorder ces privilèges au rôle de propriétaire du service :
-- Permissions to resolve the table's name.
GRANT CALLER USAGE ON DATABASE <db_name> TO ROLE <service_owner_role>;
GRANT CALLER USAGE ON SCHEMA <schema_name> TO ROLE <service_owner_role>;
-- Permissions to use a warehouse
GRANT CALLER USAGE ON WAREHOUSE <warehouse_name> TO ROLE <service_owner_role>;
-- Permissions to query the table.
GRANT CALLER SELECT ON TABLE T1 TO ROLE <service_owner_role>;
Tout rôle de votre compte disposant du privilège global MANAGE CALLER GRANT peut accorder des autorisations aux appelants. Pour plus d’informations sur les autorisations accordées à l’appelant, voir GRANT CALLER et Droits restreints de l’appelant.
Exemple¶
Un exemple de service qui utilise la fonction des droits de l’appelant lors de l’exécution des requêtes SQL pour le compte des utilisateurs est fourni. Pour plus d’informations, voir Créer un service avec les droits de l’appelant activés.
Se connecter à Snowflake via d’autres identifiants de connexion¶
Vous pouvez utiliser d’autres formes d’authentification pour la connexion à Snowflake, pas seulement le jeton OAuth fourni par Snowflake. Pour ce faire, vous créez une intégration d’accès externe (EAI) qui permet à votre conteneur de se connecter à Snowflake comme si le conteneur fonctionnait en dehors de Snowflake et se connectait via Internet. Lorsque vous vous connectez de cette manière, vous n’avez pas besoin de configurer l’hôte qui est utilisé par le client.
Note
Comme ces connexions passent par une EAI, l’authentification Snowflake applique également les politiques réseau. Si votre entreprise nécessite des politiques réseau, la connexion avec d’autres identifiants de connexion n’est pas prise en charge.
Par exemple, la connexion suivante spécifie le nom d’utilisateur et le mot de passe pour l’authentification :
conn = snowflake.connector.connect(
account = '<acct-name>',
user = '<user-name>',
password = '<password>'
)
Pour utiliser un nom d’hôte par défaut, vous devez disposer de l’intégration d’accès externe avec une règle de réseau permettant l’accès de votre service au nom d’hôte Snowflake sur Internet pour votre compte. Par exemple, si votre nom de compte est MYACCOUNT dans l’organisation MYORG, le nom d’hôte est myorg-myaccount.snowflakecomputing.com. Pour plus d’informations, voir Configuration de la sortie réseau. Les noms d’hôte Privatelink ne sont pas pris en charge
Créez une règle de réseau qui correspond au nom d’hôte d’API Snowflake de votre compte :
CREATE OR REPLACE NETWORK RULE snowflake_egress_access MODE = EGRESS TYPE = HOST_PORT VALUE_LIST = ('myorg-myaccount.snowflakecomputing.com');
Créez une intégration à l’aide de la règle de réseau précédente :
CREATE EXTERNAL ACCESS INTEGRATION snowflake_egress_access_integration ALLOWED_NETWORK_RULES = (snowflake_egress_access) ENABLED = TRUE;
Configuration de la base de données et du contexte du schéma pour l’exécution de SQL¶
En plus de fournir des identifiants de connexion, Snowflake fournit également la base de données et le contexte de schéma dans lesquels le service est créé. Le code du conteneur peut utiliser ces informations pour exécuter SQL dans le même contexte de base de données et de schéma que le service.
Cette section présente deux concepts :
La logique utilisée par Snowflake pour déterminer la base de données et le schéma dans lesquels créer votre service.
La méthode par laquelle Snowflake transmet cette information à vos conteneurs, permettant ainsi au code du conteneur d’exécuter SQL dans le même contexte de base de données et de schéma.
Snowflake utilise le nom du service pour déterminer la base de données et le schéma dans lesquels créer un service :
Exemple 1 : dans les commandes CREATE SERVICE et EXECUTE JOB SERVICE suivantes, le nom du service ne spécifie pas explicitement une base de données et un nom de schéma. Snowflake crée le service et le service de tâche dans la base de données et le schéma actuels.
-- Create a service. CREATE SERVICE test_service IN COMPUTE POOL ... -- Execute a job service. EXECUTE JOB SERVICE IN COMPUTE POOL tutorial_compute_pool NAME = example_job_service ...
Exemple 2 : dans les commandes CREATE SERVICE et EXECUTE JOB SERVICE suivantes, le nom du service comprend une base de données et un nom de schéma. Snowflake crée le service et le service de tâche dans la base de données (
test_db) et le schéma (test_schema) spécifiés, quel que soit le schéma actuel.-- Create a service. CREATE SERVICE test_db.test_schema.test_service IN COMPUTE POOL ... -- Execute a job service. EXECUTE JOB SERVICE IN COMPUTE POOL tutorial_compute_pool NAME = test_db.test_schema.example_job_service ...
Lorsque Snowflake démarre un service, Snowflake fournit les informations relatives à la base de données et au schéma aux conteneurs en cours d’exécution en utilisant les variables d’environnement suivantes :
SNOWFLAKE_DATABASE
SNOWFLAKE_SCHEMA
Le code de votre conteneur peut utiliser des variables d’environnement dans le code de connexion pour déterminer la base de données et le schéma à utiliser, comme le montre cet exemple :
conn = snowflake.connector.connect(
host = os.getenv('SNOWFLAKE_HOST'),
account = os.getenv('SNOWFLAKE_ACCOUNT'),
token = get_login_token(),
authenticator = 'oauth',
database = os.getenv('SNOWFLAKE_DATABASE'),
schema = os.getenv('SNOWFLAKE_SCHEMA')
)
Exemple
Dans le tutoriel 2, vous créez un service de tâche Snowflake qui se connecte à Snowflake et exécute des instructions SQL. Les étapes suivantes résument la manière dont le code du tutoriel utilise les variables d’environnement :
Dans la configuration commune (voir la section Configuration commune), vous créez des ressources, notamment une base de données et un schéma. Vous définissez également la base de données et le schéma actuels pour la session :
USE DATABASE tutorial_db; ... USE SCHEMA data_schema;
Après avoir créé un service de tâche (exécution de EXECUTE JOB SERVICE), Snowflake démarre le conteneur et définit les variables d’environnement suivantes dans le conteneur en fonction de la base de données et du schéma actuels de la session :
SNOWFLAKE_DATABASE est défini sur « TUTORIAL_DB »
SNOWFLAKE_SCHEMA est défini sur « DATA_SCHEMA »
Le code de la tâche (voir
main.pydans le tutoriel 2) lit ces variables d’environnement :SNOWFLAKE_DATABASE = os.getenv('SNOWFLAKE_DATABASE') SNOWFLAKE_SCHEMA = os.getenv('SNOWFLAKE_SCHEMA')
Le code de la tâche définit la base de données et le schéma comme le contexte dans lequel exécuter les instructions SQL (fonction
run_job()dansmain.py) :{ "account": SNOWFLAKE_ACCOUNT, "host": SNOWFLAKE_HOST, "authenticator": "oauth", "token": get_login_token(), "warehouse": SNOWFLAKE_WAREHOUSE, "database": SNOWFLAKE_DATABASE, "schema": SNOWFLAKE_SCHEMA } ...
Note
SNOWFLAKE_ACCOUNT, SNOWFLAKE_HOST, SNOWFLAKE_DATABASE, SNOWFLAKE_SCHEMA sont des variables d’environnement que Snowflake génère pour le conteneur d’application, mais SNOWFLAKE_WAREHOUSE ne l’est pas (le code de l’application du tutoriel 2 a créé cette variable parce que Snowflake ne transmet pas de nom d’entrepôt à un conteneur).
Spécification de l’entrepôt pour votre conteneur¶
Si votre service se connecte à Snowflake pour exécuter une requête dans un entrepôt Snowflake, vous disposez des options suivantes pour spécifier un entrepôt :
Spécifiez un entrepôt dans votre code d’application. Spécifiez un entrepôt dans le cadre de la configuration de la connexion lorsque vous démarrez une session Snowflake pour exécuter des requêtes dans votre code. Pour un exemple, voir le tutoriel 2.
Spécifiez un entrepôt par défaut lors de la création d’un service. Spécifiez le paramètre facultatif QUERY_WAREHOUSE dans la commande CREATE SERVICE (ou EXECUTE JOB SERVICE) pour fournir un entrepôt par défaut. Si votre code d’application ne fournit pas d’entrepôt dans le cadre de la configuration de la connexion, Snowflake utilise l’entrepôt par défaut. Utilisez la commande ALTER SERVICE pour modifier l’entrepôt par défaut.
Note
L’entrepôt spécifié à l’aide du paramètre QUERY_WAREHOUSE est le paramètre par défaut uniquement pour l’utilisateur de service. Lorsque le service se connecte à Snowflake au nom d’un autre utilisateur — dans le contexte de scénario des droits de l’appelant, Snowflake utilise l’entrepôt par défaut de l’utilisateur.
Si vous spécifiez un entrepôt à l’aide des deux méthodes, c’est l’entrepôt spécifié dans le code d’application qui est utilisé.
Accéder à l’historique des requêtes des utilisateurs du service¶
Vous pouvez trouver les requêtes exécutées par votre service en tant qu’utilisateur du service en filtrant la fonction Vue QUERY_HISTORY ou QUERY_HISTORY où user_type est SNOWFLAKE_SERVICE.
Exemple 1 : récupérer les requêtes exécutées par un service.
SELECT *
FROM snowflake.account_usage.query_history
WHERE user_type = 'SNOWFLAKE_SERVICE'
AND user_name = '<service_name>'
AND user_database_name = '<service_db_name>'
AND user_schema_name = '<service_schema_name>'
order by start_time;
Dans la clause WHERE :
user_name = '<service_name>': Vous spécifiez le nom de service en tant que nom de l’utilisateur, car un service exécute des requêtes en tant qu’utilisateur de service et le nom de l’utilisateur de service est le même que le nom du service.user_type = 'SNOWFLAKE_SERVICE'etuser_name = '<service_name>': Cela limite le résultat de la requête à récupérer uniquement les requêtes exécutées par un service.user_database_nameetuser_schema_name: Pour un utilisateur de service, il s’agit de la base de données et du schéma du service.
Vous pouvez obtenir les mêmes résultats en appelant la fonction QUERY_HISTORY.
SELECT *
FROM TABLE(<service_db_name>.information_schema.query_history())
WHERE user_database_name = '<service_db_name>'
AND user_schema_name = '<service_schema_name>'
AND user_type = 'SNOWFLAKE_SERVICE'
AND user_name = '<service_name>'
order by start_time;
Dans la clause WHERE :
user_type = 'SNOWFLAKE_SERVICE'etuser_name = '<service_name>'limitent le résultat de la requête pour récupérer uniquement les requêtes exécutées par un service.Les noms
user_database_nameetuser_schema_name(pour un utilisateur de service) sont la base de données et le schéma du service.
Exemple 2 : récupérer les requêtes exécutées par les services et les informations correspondantes sur les services.
SELECT query_history.*, services.*
FROM snowflake.account_usage.query_history
JOIN snowflake.account_usage.services
ON query_history.user_name = services.service_name
AND query_history.user_schema_id = services.service_schema_id
AND query_history.user_type = 'SNOWFLAKE_SERVICE'
La requête rejoint les vues QUERY_HISTORY et SERVICES pour récupérer des informations sur les requêtes et les services qui ont exécuté les requêtes. Remarques :
Pour les requêtes exécutées par les services, le
query_history.user_nameest le nom de l’utilisateur du service, qui est le même que le nom du service.La requête joint les vues à l’aide des IDs de schémas (pas le nom des schémas) pour vous assurer que vous faites référence au même schéma, car si vous supprimez et recréez un schéma, l’ID du schéma change, mais le nom reste le même.
Vous pouvez ajouter des filtres facultatifs à la requête. Par exemple :
Filtre
query_historypour récupérer uniquement les services qui ont exécuté des requêtes spécifiques.Filtre
servicespour récupérer uniquement les requêtes exécutées par des services spécifiques.
Exemple 3 : pour chaque service, récupérer les informations sur l’utilisateur du service.
SELECT services.*, users.*
FROM snowflake.account_usage.users
JOIN snowflake.account_usage.services
ON users.name = services.service_name
AND users.schema_id = services.service_schema_id
AND users.type = 'SNOWFLAKE_SERVICE'
La requête joint les vues SERVICES et USERS dans le schéma ACCOUNT_USAGE permettant de récupérer les services et les informations sur les utilisateurs des services. Remarques :
Lorsqu’un service exécute des requêtes, il exécute les requêtes en tant qu’utilisateur du service et le nom de l’utilisateur du service est le même que le nom du service. Par conséquent, vous spécifiez la condition de jointure :
users.name = services.service_name.Les noms de service ne sont uniques qu’au sein d’un schéma. Par conséquent, la requête spécifie la condition de jointure (
users.schema_id = services.service_schema_id) pour garantir que chaque utilisateur de service est associé au service spécifique auquel il appartient (et non à un autre service du même nom exécuté dans des schémas différents).