在托管 PostgreSQL 服务器的服务器中,有一个非常特定的目录,将定期加载一系列 .csv 文件以更新其中一个数据库。我想让上传这些文件中包含的数据的过程尽可能自动化,因此我创建了一个.sh
脚本来执行此操作。这是一个简单的for
循环,遍历该目录中的 .csv 文件集,并将它们的名称作为参数传递给\COPY
句子。
现在,由于服务器管理员对他们的服务器有一点了解,他们想让我们只访问 SQL 服务器而不是底层的 unix 服务器。所以,问题来了:
有没有办法通过从数据库内部执行的存储过程来完成上述任务?你真的能以这种方式从数据库中读取和访问路径及其内容吗?整个 .csv 文件集可能会有所不同,所以我认为硬编码的解决方案不会起作用,而且它看起来很脏(尽管,如果这是我让它工作的唯一方法,那就这样吧)。
我的猜测是你不能但是......你永远不知道。
我不确定您是如何从中访问 SQL 服务器的。但是,如果您要继续访问
psql
,也许您可以解决他们的安全\!
问题psql
pg_ls_dir
有一个非常接近您需要的内置功能。有两个与安全相关的警告:
关于成为超级用户的需要,任何解决方案无论如何都会有这个要求,因为它是一个设计特性,普通用户对文件系统的访问权限为零。
DBA(超级用户)可以通过定义了访问权限的代理功能授予对其他禁止的特定功能的
SECURITY DEFINER
访问权限。例如:
关于第二个问题,DBA 可以从
$PGDATA
目录内部创建到任何目录的符号链接,并pg_ls_dir
跟随它,因此真正的上传目录可以是文件系统上的任何位置。如果系统管理员同意此设置,作为非特权用户,您最终可以运行一个与 shell 脚本功能匹配的简单 plpgsql 函数:
由于
COPY FROM file
它本身需要成为超级用户,因此该功能也需要SECURITY DEFINER
由超级用户进行验证、拥有和检查。这取决于你想走多远,对吧?如果他们让你跑
plperlu
,如果你真的想成为一个巨大的冲洗喷嘴,你可以调用Net::Dropbear::SSHd:
postgresql-plperl-9.5
包——它通常是预先打包的,听起来无害)CREATE EXTENSION plperlu;
sudo cpan Net::Dropbear::SSHd;
(或在本地安装并使用local::lib
)这是此类功能的示例,
如果你的数据库没有 sshd,你就不能数据。