¿Cómo influye search_path en la resolución del identificador y el "esquema actual"?
¿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?
¿ 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 TABLE
comando 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_catalog
automáticamente forman parte de la ruta de búsqueda y se buscan primero , en este orden. El manual:
pg_catalog
siempre 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ícitamentepg_catalog
al 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_temp
viene 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
.
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 devueltoCURRENT_USER
, si existe dicho esquema y el usuario tieneUSAGE
permiso para ello. (Si no,$user
se ignora).Configúrelo como predeterminado para una base de datos :
ALTER DATABASE test SET search_path = blarg,public;
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;
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;
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;
Establezca un alcance específico
search_path
para una función (para estar a salvo de usuarios malintencionados con privilegios suficientes). Lea sobre EscrituraSECURITY DEFINER
de 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
SET
se hubiera emitido ninguno en la sesión actual.
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