【问题标题】:How to get dbplyr in_schema to reference different warehouse如何让 dbplyr in_schema 引用不同的仓库
【发布时间】:2021-12-24 15:30:21
【问题描述】:

我正在使用 dbplyr 访问雪花中的一个复杂仓库,其中包含多个数据库。我对其中一个有写访问权,对其余的有读访问权。样本结构

WH_a
 - schema_a 
   - table_aa
 - schema_b
   - table_ba
WH_b
 - schema_c
    - table_ca

按照 dbplyr 文档,我将工作数据库和架构设置为“WH_a.schema_a”:

dbGetQuery(conn, "USE DATABASE WH_a")
dbGetQuery(conn, "USE SCHEMA schema_a")

并尝试创建表引用。简单的表引用在相同的架构中工作正常:

aa <- tbl(conn, "table_aa") 

如果我想引用不同模式(相同 WH_a)中的表,我可以毫无问题地使用 in_schema() 函数:

ba <- tbl(conn, in_schema("schema_b", "table_ba")) 

但是,当我尝试引用不同仓库中的表时遇到了问题。

ca <- tbl(conn, in_schema("WH_b.schema_c", "table_ca")) 

nanodbc/nanodbc.cpp:1374: 00000: SQL compilation error:
Schema 'WH_a."WH_b.schema_c"'  does not exist or not authorized.

看起来 in_schema 调用继承了当前数据库并且无法上一层。我一直在阅读文档,但大多数示例都指的是更简单的数据库,这不是问题。测试设置和取消设置不同模式/仓库的各种组合并没有成功...最终我通过直接传递 sql 语句找到了解决方法

ca <- tbl(conn, sql("SELECT * FROM WH_b.schema_c.table_ca")) 

但是,这会创建非常丑陋(并且可能效率低下)的 SQL 代码,其中 select 语句插入到括号中,而不仅仅是表名。它更难阅读,而且从长远来看确实是正确的做法

有没有更简单/更有效的解决方案?

非常感谢

【问题讨论】:

  • 按照this的回答,试试tbl(con, in_schema(sql("db_name.schema_name"),"table_name"))。这与@Fieldy 下面的回复一致。

标签: sql snowflake-cloud-data-platform dbplyr tbl


【解决方案1】:

这可能是因为,与 Snowflake 不同,相当多的数据库不支持跨数据库连接,因此在 dbplyr 的设计中可能没有考虑。

您可以使用sql() 函数将database.schema 或database.schema.table 字符串包含在下面的测试中似乎有效。

# Create Databases, Schemas & Tables
dbGetQuery(conn, "CREATE DATABASE WH_A")
dbGetQuery(conn, "CREATE SCHEMA SCHEMA_A")
dbGetQuery(conn, "USE DATABASE WH_A")
dbGetQuery(conn, "USE SCHEMA SCHEMA_A")
dbGetQuery(conn, "CREATE TABLE TABLE_AA as 
                         select c1, c2
                          from (values (1, 'one'), (2, 'two')) as v1 (c1, c2);")
dbGetQuery(conn, "CREATE SCHEMA SCHEMA_B")
dbGetQuery(conn, "USE SCHEMA SCHEMA_B")
dbGetQuery(conn, "CREATE TABLE TABLE_BA as 
                         select c1, c2
                          from (values (1, 'one'), (2, 'two')) as v1 (c1, c2);")
dbGetQuery(conn, "CREATE DATABASE WH_B")
dbGetQuery(conn, "USE DATABASE WH_B")
dbGetQuery(conn, "CREATE SCHEMA SCHEMA_C")
dbGetQuery(conn, "USE SCHEMA SCHEMA_C")
dbGetQuery(conn, "SELECT CURRENT_DATABASE() as db, CURRENT_SCHEMA() as sc;")
dbGetQuery(conn, "CREATE TABLE TABLE_CA as 
                         select c1, c2
                          from (values (1, 'one'), (2, 'two')) as v1 (c1, c2);")
# Create tbl for TABLE_AA
dbGetQuery(conn, "USE DATABASE WH_A")
dbGetQuery(conn, "USE SCHEMA SCHEMA_A")
(aa <- tbl(conn, "TABLE_AA") )
aa$ops # Check database.schema.table reference

# Create tbl for TABLE_BA
(ba <- tbl(conn, in_schema("SCHEMA_B", "TABLE_BA")) )
ba$ops

# Create tbl for TABLE_CA
(ca <- tbl(conn, in_schema("WH_B.SCHEMA_C", "TABLE_CA")))       # Fails
(ca <- tbl(conn, in_schema(sql("WH_B.SCHEMA_C"), "TABLE_CA")))  # Works
ca$ops
# From: WH_B.SCHEMA_C."TABLE_CA"
# <Table: WH_B.SCHEMA_C."TABLE_CA">
ca <- tbl(conn, sql("WH_B.SCHEMA_C.TABLE_CA"))  # Also Works
ca$ops
# From: <derived table>
# <Table: WH_B.SCHEMA_C.TABLE_CA>

# Check cross schema join works
inner_join(aa,ba,by='C1')
# Check cross database join works  
inner_join(aa,ca,by='C1')

# Clean up 
dbGetQuery(conn, "DROP DATABASE WH_A")
dbGetQuery(conn, "DROP DATABASE WH_B")

如果您的数据库对象使用大小写混合,您需要注意在 Sql() 中正确引用它们

dbGetQuery(conn, 'CREATE DATABASE "WH_b" ')
dbGetQuery(conn, 'USE DATABASE "WH_b" ')
dbGetQuery(conn, 'CREATE SCHEMA "schema_c" ')
dbGetQuery(conn, 'USE SCHEMA "schema_c" ')
dbGetQuery(conn, 'SELECT CURRENT_DATABASE() as db, CURRENT_SCHEMA() as sc;')
dbGetQuery(conn, 'CREATE TABLE "table_ca" as 
                         select c1, c2
                          from (values (1, \'one\'), (2, \'two\')) as v1 (c1, c2);')
dbGetQuery(conn, 'SELECT * FROM  "WH_b"."schema_c"."table_ca";')

(ca <- tbl(conn, sql(' "WH_b"."schema_c"."table_ca" ')))  # Quoted mixed case object names also Works
ca$ops

# Clean up 
dbGetQuery(conn, 'DROP DATABASE "WH_b" ')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 2019-07-21
    相关资源
    最近更新 更多