web-dev-qa-db-fra.com

Comment le chemin de recherche influence-t-il la résolution de l'identifiant et le "schéma actuel"

Est-il possible de définir dans quel schéma de nouvelles tables sont créées par défaut? (Référé par "noms de table non qualifiés".)

J'ai vu quelques détails sur l'utilisation du "chemin de recherche" dans Postgres, mais je pense que cela ne fonctionne que lors de la récupération des données, pas de la création.

J'ai un tas de scripts SQL, qui créent de nombreuses tables. Au lieu de modifier les scripts, je souhaite définir la base de données créer des tables dans un schéma spécifique par défaut - quand ils ont des noms non qualifiés.

Est-ce possible?

45
thyandrecardoso

Le chemin de recherche est en effet ce que vous recherchez:

% create schema blarg;
% set search_path to blarg;
% create table foo (id int);
% \d
       List of relations
 Schema | Name | Type  | Owner 
--------+------+-------+-------
 blarg  | foo  | table | pgsql
27
Alex Howansky

Quel est le chemin de recherche?

Par documentation:

[...] les tables sont souvent désignées par des noms non qualifiés, qui se composent uniquement du nom de la table. Le système détermine à quelle table il faut faire référence en suivant un chemin de recherche, qui est une liste de schémas dans lesquels regarder .

Accentuation sur moi. Cela explique la résolution de l'identifiant , et le "schéma actuel" est, - par documentation:

Le premier schéma nommé dans le chemin de recherche est appelé schéma actuel . En plus d'être le premier schéma recherché, il s'agit également du schéma dans lequel de nouvelles tables seront créées si la commande CREATE TABLE Ne spécifie pas de nom de schéma.

Accentuation sur moi. Les schémas système pg_temp (schéma des objets temporaires de la session en cours) et pg_catalog font automatiquement partie du chemin de recherche et ont cherché d'abord, dans cet ordre. Par documentation:

pg_catalog Fait toujours partie du chemin de recherche. S'il n'est pas nommé explicitement dans le chemin, il est implicitement recherché avant de rechercher les schémas du chemin. Cela garantit que les noms intégrés seront toujours trouvables. Cependant, vous pouvez explicitement placer pg_catalog À la fin de votre chemin de recherche si vous préférez que les noms définis par l'utilisateur remplacent les noms intégrés.

Accentuation audacieuse selon l'original. Et pg_temp Vient avant cela, à moins qu'il ne soit placé dans une position différente.

Comment le régler?

Vous avez différentes options pour définir réellement la variable d'exécution search_path .

  1. Définissez un cluster par défaut pour tous les rôles dans toutes les bases de données dans postgresql.conf (et rechargez). Attention à ça!

    search_path = 'blarg,public'
    

    livré par défaut pour ce paramètre est:

    search_path = "$user",public
    

    Le premier élément spécifie qu'un schéma portant le même nom que l'utilisateur actuel doit être recherché. Si aucun schéma de ce type n'existe, l'entrée est ignorée.

  2. Définissez-le par défaut pour une base de données :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Définissez-le par défaut pour le rôle avec lequel vous vous connectez (à l'échelle du cluster):

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. Ou même (souvent mieux!) Par défaut pour le rôle uniquement dans une base de données donnée :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Écrivez la commande en haut de votre script (Ou exécutez-la à tout moment de votre session :

    SET search_path = blarg,public;
    
  6. Définissez un search_path Spécifique pour la portée d'une fonction (pour être à l'abri des utilisateurs malveillants disposant de privilèges suffisants). Lisez à propos de Écriture des fonctions SECURITY DEFINER En toute sécurité dans le manuel.

CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;

Un nombre plus élevé dans ma liste l'emporte sur un nombre inférieur.
Le le manuel a encore plus de façons , comme définir des variables d'environnement ou utiliser des options de ligne de commande.

Pour voir le paramètre actuel:

SHOW search_path;

Pour réinitialiser it:

RESET search_path;

Par documentation :

La valeur par défaut est définie comme la valeur que le paramètre aurait eu si aucun SET n'avait jamais été émis pour lui dans la session en cours.

70
Erwin Brandstetter