pyspark - SparkSQL(Databricks):将数据插入到由不同角色创建的雪花表中
问题描述
我MYSCHEMA.TEST_SNOWFLAKE_ROLE_T
在 Snowflake 中有一个使用该角色创建的表CONSOLE_USER.
MYSCHEMA
有一个FUTURE GRANTS
与之关联的,它BATCH_USER
为在模式下创建的任何表的角色授予以下权限MYSCHEMA - DELETE, INSERT, REFERENCES, SELECT, TRUNCATE, UPDATE.
该角色BATCH_USER
还具有架构上CREATE STAGE
的USAGE
权限MYSCHEMA
。
属于该角色的第二个用户BATCH_USER
尝试使用以下 Spark SQL (Databricks) 将数据从数据帧插入到同一个表中,但失败并显示权限不足错误消息。
df.write.mode(op_mode) \
.format("snowflake") \
.options(**self.sfoptions) \
.option("dbtable", snowflake_tbl_name) \
.option("truncate_table", "on") \
.save
出现以下错误消息:
Py4JJavaError: An error occurred while calling o908.save.
: net.snowflake.client.jdbc.SnowflakeSQLException: SQL access control error
: Insufficient privileges to operate on table 'TEST_SNOWFLAKE_ROLE_T')
该角色CONSOLE_USER
对表具有所有权,因此该角色BATCH_USER
将无法删除该表,但添加该选项option("truncate_table", "on")
应该可以防止自动覆盖表模式。
我已经多次浏览了可用的 Snowflake 和 Databricks 文档,但似乎无法弄清楚是什么导致了权限不足的问题。
任何帮助深表感谢!
解决方案
我最终想通了。
发生错误是因为该表是由角色创建的,该角色CONSOLE_USER
保留了对该表的所有权权限。
Snowflake 的 Spark 连接器使用临时表来写入数据。如果数据加载操作成功,则删除原始目标表并将临时表重命名为原始目标表的名称。
现在,为了重命名表或交换两个表,用于执行操作的角色必须对表具有 OWNERSHIP 权限。在上述情况下,所有权从未转移给角色BATCH_USER
,因此出现错误。
df.write.mode(op_mode) \
.format("snowflake") \
.options(**self.sfoptions) \
.option("dbtable", snowflake_tbl_name) \
.option("truncate_table", "on") \
.option("usestagingtable", "off") \
.save
解决方案是完全避免使用临时表,尽管按照文档,Snowflake 强烈建议使用一个。
推荐阅读
- c# - 登录后发送数据到其他表单C#
- c# - Await 不会阻塞调用线程
- java - 如何将多个 Map/List/Array 从 API url 传递到 Java 中的 RestController?
- asp.net - 通过 ftp 上传到 hostgator 的 ASP.net Web 应用程序不允许查看它们。它抛出403错误
- sql-server - 锁挂起(死锁?)有两个事务
- reactjs - 如何使用 Material UI 在某些断点处隐藏/显示元素?
- ios - 当 git 提交时 Xcode 项目应该跟踪哪些文件
- php - 在 Debian 10 中安装 php7.4-cgi
- python - 如何处理在窗口生成的csv末尾附加的空行?
- amazon-web-services - 使用 AWS 控制台自动激活接收账单警报选项