¿Quiere el archivo resultante en el servidor o en el cliente?
Lado del servidor
Si desea algo fácil de reutilizar o automatizar, puede usar el comando COPY incorporado de Postgresql. por ejemplo
Copy (Select * From foo) To '/tmp/test.csv' With CSV DELIMITER ',' HEADER;
Este enfoque se ejecuta completamente en el servidor remoto - no puede escribir en su PC local. También debe ejecutarse como un "superusuario" de Postgres (normalmente llamado "raíz") porque Postgres no puede evitar que haga cosas desagradables con el sistema de archivos local de esa máquina.
En realidad, eso no significa que deba estar conectado como superusuario (automatizar eso sería un riesgo de seguridad de otro tipo), porque puede usar el SECURITY DEFINER
opción para CREATE FUNCTION
para hacer una función que ejecuta como si fueras un superusuario .
La parte crucial es que su función está allí para realizar verificaciones adicionales, no solo para eludir la seguridad, por lo que podría escribir una función que exporte los datos exactos que necesita, o podría escribir algo que pueda aceptar varias opciones siempre que cumplir con una estricta lista blanca. Tienes que comprobar dos cosas:
- ¿Qué archivos ¿Se debe permitir al usuario leer/escribir en el disco? Este podría ser un directorio en particular, por ejemplo, y el nombre del archivo podría tener un prefijo o una extensión adecuados.
- ¿Qué tablas ¿Debe el usuario ser capaz de leer/escribir en la base de datos? Esto normalmente estaría definido por
GRANT
s en la base de datos, pero la función ahora se ejecuta como superusuario, por lo que las tablas que normalmente estarían "fuera de los límites" serán totalmente accesibles. Probablemente no quiera permitir que alguien invoque su función y agregue filas al final de su tabla de "usuarios"...
He escrito una publicación de blog que amplía este enfoque, incluidos algunos ejemplos de funciones que exportan (o importan) archivos y tablas que cumplen condiciones estrictas.
Lado del cliente
El otro enfoque es hacer el manejo de archivos en el lado del cliente , es decir, en su aplicación o script. El servidor de Postgres no necesita saber en qué archivo está copiando, simplemente escupe los datos y el cliente los coloca en alguna parte.
La sintaxis subyacente para esto es COPY TO STDOUT
y las herramientas gráficas como pgAdmin lo envolverán en un agradable diálogo.
El psql
cliente de línea de comandos tiene un "meta-comando" especial llamado \copy
, que toma las mismas opciones que el COPY
"real" , pero se ejecuta dentro del cliente:
\copy (Select * From foo) To '/tmp/test.csv' With CSV
Tenga en cuenta que no hay terminación ;
, porque los metacomandos terminan con una nueva línea, a diferencia de los comandos SQL.
De los documentos:
No confunda COPY con la instrucción psql \copy. \copy invoca COPY FROM STDIN o COPY TO STDOUT y luego obtiene/almacena los datos en un archivo accesible para el cliente psql. Por lo tanto, la accesibilidad a los archivos y los derechos de acceso dependen del cliente en lugar del servidor cuando se usa \copy.
Su lenguaje de programación de aplicaciones puede también tiene soporte para empujar o recuperar los datos, pero generalmente no puede usar COPY FROM STDIN
/TO STDOUT
dentro de una declaración SQL estándar, porque no hay forma de conectar el flujo de entrada/salida. El controlador PostgreSQL de PHP (no PDO) incluye pg_copy_from
muy básico y pg_copy_to
funciones que copian hacia/desde una matriz de PHP, lo que puede no ser eficiente para grandes conjuntos de datos.