¿Cómo influye search_path en la resolución del identificador y el "esquema actual"?

Resuelto thyandrecardoso asked hace 12 años • 2 respuestas

¿Es posible definir en qué esquema se crean nuevas tablas de forma predeterminada? (Referido por "nombres de tablas no calificados".)

He visto algunos detalles sobre el uso de la "ruta de búsqueda" en Postgres, pero creo que solo funciona al recuperar datos, no al crearlos.

Tengo un montón de scripts SQL que crean muchas tablas. En lugar de modificar los scripts, quiero configurar la base de datos para crear tablas en un esquema específico de forma predeterminada, cuando tienen nombres no calificados.

es posible?

thyandrecardoso avatar Jan 30 '12 23:01 thyandrecardoso
Aceptado

¿ Cuál es la ruta de búsqueda de esquemas search_path?

El manual:

[...] menudo se hace referencia a las tablas con nombres no calificados, que constan sólo del nombre de la tabla. El sistema determina a qué tabla se refiere siguiendo una ruta de búsqueda, que es una lista de esquemas para buscar .

El énfasis en negrita es mío. Esto explica la resolución del identificador .

El "esquema actual" (o "esquema predeterminado") es, según la documentación:

El primer esquema nombrado en la ruta de búsqueda se denomina esquema actual . Además de ser el primer esquema buscado, también es el esquema en el que se crearán nuevas tablas si el CREATE TABLEcomando no especifica un nombre de esquema.

El énfasis en negrita es mío. Los esquemas del sistema pg_temp(esquema para objetos temporales de la sesión actual) y pg_catalogautomáticamente forman parte de la ruta de búsqueda y se buscan primero , en este orden. El manual:

pg_catalogsiempre es efectivamente parte de la ruta de búsqueda. Si no se nombra explícitamente en la ruta, se busca implícitamente antes de buscar en los esquemas de la ruta. Esto garantiza que siempre se podrán encontrar los nombres integrados. Sin embargo, puede colocarlo explícitamente pg_catalogal final de su ruta de búsqueda si prefiere que los nombres definidos por el usuario anulen los nombres integrados.

Énfasis en negrita según el original. Y pg_tempviene antes de eso, a menos que se coloque en una posición diferente.

¿Cómo configurarlo?

Hay varias formas de configurar la variable de tiempo de ejecución search_path.

  1. Establezca un valor predeterminado para todo el clúster para todos los roles en todas las bases de datos postgresql.conf(y vuelva a cargar). ¡Cuidado con eso!

     search_path = 'blarg,public'
    

    El valor predeterminado de fábrica para esta configuración es:

     search_path = "$user",public
    

    Nota:

    El primer elemento especifica que se buscará un esquema con el mismo nombre que el usuario actual. Si no existe tal esquema, la entrada se ignora.

    Y:

    Si uno de los elementos de la lista es el nombre especial $user, entonces se sustituye el esquema que tiene el nombre devuelto CURRENT_USER, si existe dicho esquema y el usuario tiene USAGEpermiso para ello. (Si no, $userse ignora).

  2. Configúrelo como predeterminado para una base de datos :

     ALTER DATABASE test SET search_path = blarg,public;
    
  3. Configúrelo como predeterminado para el rol con el que se conecta (efectivo en todo el clúster):

     ALTER ROLE foo SET search_path = blarg,public;
    
  4. O incluso (¡a menudo lo mejor!) como valor predeterminado para una función en una base de datos :

     ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Escriba el comando en la parte superior de su script. O ejecútelo en su sesión de base de datos :

     SET search_path = blarg,public;
    
  6. Establezca un alcance específico search_pathpara una función (para estar a salvo de usuarios malintencionados con privilegios suficientes). Lea sobre Escritura SECURITY DEFINERde funciones de forma segura en el manual.

    CREAR FUNCIÓN foo()
      DEVOLUCIONES nulas
      IDIOMA plpgsql DEFINIDOR DE SEGURIDAD CONJUNTO search_path=blarg,public,pg_temp
      COMO
    $func$
    COMENZAR
       -- hacer cosas
    FIN
    $func$;

El número más alto en la lista triunfa sobre el número más bajo.
El manual tiene aún más formas , como configurar variables de entorno o usar opciones de línea de comandos.

Para ver la configuración actual:

SHOW search_path;

Para restablecerlo :

RESET search_path;

El manual:

El valor predeterminado se define como el valor que habría tenido el parámetro, si nunca SETse hubiera emitido ninguno en la sesión actual.

Erwin Brandstetter avatar Jan 30 '2012 17:01 Erwin Brandstetter

La ruta de búsqueda es de hecho lo que desea:

% 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
Alex Howansky avatar Jan 30 '2012 16:01 Alex Howansky