如何在 dplyr 中创建 left_join(..., copy=TRUE) 而不授予 INSERT 权限

FvD*_*FvD 5 mysql r dplyr

我们需要将数据库表与 Excel 文件的内容连接起来。使用 a 很简单dplyr left_join,但需要copy=TRUE在连接中设置它,因为数据不是来自同一源。这又意味着只有当数据库用户具有 INSERT 权限时代码才会运行,以便left_join可以在 /tmp 文件夹中创建临时表。

有没有办法copy=TRUE left_join在不授予 INSERT 权限的情况下执行此操作?访问数据进行分析的数据库用户实际上应该只是读者。

如果未授予插入权限,则会出现如下错误:

Error in .local(conn, statement, ...) : 
  could not run statement: INSERT command denied to user 
  'reader'@'192.168.135.1' for table 'utiexriryc'
Run Code Online (Sandbox Code Playgroud)

将出现(每次连接时都有不同的随机表名称)。

一个简短的可重现示例很困难,因为它需要一个数据库连接(在本例中为 mysql wtih src_mysql())和一个 excel 文件(在本例中为 读取readxl)。连接看起来像:

df.biozones <- db.sites %>% 
  left_join(ef.join_site_ids, by=c("site_id"="id"), copy=TRUE) %>% 
  collect()
Run Code Online (Sandbox Code Playgroud)

其中 db.sites 是一个 mysql 数据库表,ef.join_site_ids 是一个使用 readxl 读取的 Excel 电子表格中的 data.frame。

有没有办法在 dplyr 中执行上述操作并避免为读取数据的用户授予 INSERT 权限?

FvD*_*FvD 2

虽然没有办法直接按照我的要求做,正如@hadley所说,但有不同的方式来看待这个问题。我花了一些时间才理解 dplyr 将每个连接视为差异源(或src简称)。src内存中的对象集合始终存在。

所以在我的问题中,我实际上正在处理三个来源:

  1. 内存中的对象
  2. 数据库_1
  3. 数据库_2

这三者之间的任何连接都需要 dplyr 的权限来创建临时表并将其插入其中。这三者中任何一个的任何加入都不会成为问题。因此,当您无法获得数据库的附加权限时,有(至少)三种可能的方法来处理此问题。

1.将所有内容加载到内存中

如果您将两个数据库中所需的所有对象放入内存中,那么您将把它们放入共享数据库中src,并且能够对它们进行任何连接。Dplyr 提供了collect()执行此操作的函数:

db_table_of_interest <- tbl(Database_1, "table_of_interest")
df_table_of_interest <- collect(db_table_of_interest).
Run Code Online (Sandbox Code Playgroud)

事实上,您将把表变成本地数据框。您需要对所有感兴趣的数据库中的所有感兴趣的表执行此操作。只要您有足够的 RAM 来保存您正在读取的所有数据,它就可以正常工作。

2. 在数据库之间复制标识符

如果(就像我们的情况)您需要在两个数据库之间连接记录标识符(例如站点或样本 ID),而这两个数据库在不同 ID 下具有相同站点,那么最简单的方法是将两个数据库中的表中的 ID 加倍。因此,不要使用外部表来列出每个数据库中每个站点的所有 ID 并设置匹配项,而是在每个数据库的 site_table 中添加一列并引用另一列。

只要您不需要使用实际数据设置连接表,那么就可以了。例如,如果您需要读取按物种分类的站点和按环境分类的站点表,其中物种和环境数据存储在单独的数据库中,并且每个站点都有不同的 ID。

如果您确实需要连接表,那么至少您可以在执行collect()并读取内存中的所有内容之前在两个数据库中进行预选择。当有大量数据需要读取时,这将节省您的内存需求。

3. 将所有内容复制到一个分析数据库中

如果由于某种原因无法使用更多内存,那么理论上您可以首先将所有数据复制到一个数据库中。我无法想象这在任何情况下都是可行的选择,除非只有几个感兴趣的表,以便将它们合并到一个新的联合数据库中是可行的。也许在数据集非常大并且不会改变的情况下。

如果我在此列表中遗漏了某个选项,我很高兴知道您可能找到了哪些其他解决方案。