如何使用 R DBI 的 dbWriteTable() 将二进制数据写入 SQLite?

2024-01-28

例如,如何执行以下等效的 SQL(插入到BINARY(16) field)

INSERT INTO Table1 (MD5) VALUES (X'6717f2823d3202449201145073ab871A'),(X'6717f2823d3202449301145073ab371A')

using dbWriteTable()? Doing

dbWriteTable(db, "Table1", data.frame(MD5 = "X'6717f2823d3202449201145073ab871A'", ...), append = T, row.names = F)

似乎不起作用 - 它将值写入文本。

最后,我将拥有一个我想要编写的哈希值的大 data.frame,并且非常适合使用dbWriteTable。但我就是不知道如何INSERT the data.frame into binary数据库字段。


所以这里有两种似乎可行的可能性。第一个用途dbSendQuery(...)循环(你可能已经想到了这一点......)。

db.WriteTable = function(con,table,df) {  # no error checking whatsoever...
  require(DBI)
  field <- colnames(df)[1] 
  for (i in 1:nrow(df)) {
    query <- sprintf("INSERT INTO %s (%s) VALUES (X'%s')",table,field,df[i,1])
    rs    <- dbSendQuery(con,statement=query)
  }
  return(nrow(df))
}

library(DBI)
drv <- dbDriver("SQLite")
con <- dbConnect(drv)
rs  <- dbSendQuery(con, statement="CREATE TABLE hash (MD5 BLOB)")

df  <- data.frame(MD5=c("6717f2823d3202449201145073ab871A",
                        "6717f2823d3202449301145073ab371A"))

rs       <- db.WriteTable(con,"hash",df)
result.1 <- dbReadTable(con,"hash")
result.1
#                                                              MD5
# 1 67, 17, f2, 82, 3d, 32, 02, 44, 92, 01, 14, 50, 73, ab, 87, 1a
# 2 67, 17, f2, 82, 3d, 32, 02, 44, 93, 01, 14, 50, 73, ab, 37, 1a

如果你的哈希数据框非常大,那么df.WriteFast(...)做同样的事情db.WriteTable(...)只是它应该更快。

db.WriteFast = function(con.table,df) {
  require(DBI)
  field <- colnames(df)[1]
  lapply(unlist(df[,1]),function(x){
         dbSendQuery(con,
                     statement=sprintf("INSERT INTO %s (%s) VALUES (X'%s')",
                                        table,field,x))})
}

注意result.1是一个数据框,如果我们在调用中使用它dbWriteTable(...)我们可以成功地将哈希值写入 BLOB。所以这是可能的。

str(result.1)
# 'data.frame': 2 obs. of  1 variable:
#  $ MD5:List of 2
#   ..$ : raw  67 17 f2 82 ...
#   ..$ : raw  67 17 f2 82 ...

第二种方法利用了 R 的优势raw数据类型来创建结构如下的数据框架result.1,并将其传递给dbWriteTable(...)。您可能认为这很容易,但事实并非如此。

h2r = function(x) {
  bytes <- substring(x, seq(1, nchar(x)-1, 2), seq(2, nchar(x), 2))
  return(list(as.raw(as.hexmode(bytes))))
}
hash2raw = Vectorize(h2r)

df.raw=data.frame(MD5=list(1:nrow(df)))
colnames(df.raw)="MD5"
df.raw$MD5 = unname(hash2raw(as.character(df$MD5)))
dbWriteTable(con, "newHash",df.raw)
result.2 <- dbReadTable(con,"newHash")
result.2

all.equal(result.1$MD5,result.2$MD5)
# [1] TRUE

在这种方法中,我们创建一个数据框df.raw其中有一列,MD5,其中每个元素是原始字节的列表。效用函数h2r(...)获取哈希的字符表示,将其分解为向量char(2)(字节),然后将每个字节解释为十六进制(as.hexmode(...)),将结果转换为原始 (as.raw(...)),最后以列表形式返回结果。Vectorize(...)是一个包装器,允许hash2raw(...)以向量作为其参数。

就个人而言,我认为您最好使用第一种方法:它利用 SQLite 的内部机制将十六进制写入 BLOB,并且更容易理解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 R DBI 的 dbWriteTable() 将二进制数据写入 SQLite? 的相关文章

  • 如何用外部图像填充地图边界?

    我正在创建一张带有州边界的巴西地图 这可以直接使用ggplot2 and geom sf 然而 这一次 我不想用数据填充每个状态的颜色 而是想用外部图像 png 填充每个状态的边界 类似于this https online olivet e
  • 我无法下载 R 中的 reshape2 包 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我在尝试安装 R 包时收到此响应 gt installed packages reshape2 Package LibPath V
  • 正则表达式字符串中第一个和最后一个非点的位置

    我希望找到字符串的第一个和最后一个非点元素的位置 理想情况下我想这样做regex在基地R 我已经写过R解决问题的代码 不过 我对一个感兴趣regex解决方案 感谢您的任何建议 这是一个示例数据集和R代码以获得所需的结果 此代码拆分字符串并使
  • 在 R 中向散点图添加线条

    如何向图表添加线条 我做了以下 dat lt data frame xvar 1 20 rnorm 20 sd 10 yvar 1 20 rnorm 20 sd 10 zvar 1 20 rnorm 20 sd 10 plot dat 1
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • R - Plm 和 lm - 固定效应

    我有一个平衡面板数据集 df 本质上由三个变量组成 A B and Y 对于一堆独特识别的区域来说 它会随着时间的推移而变化 我想运行一个回归 其中包括区域 下面等式中的区域 和时间 年份 固定效应 如果我没记错的话 我可以通过不同的方式来
  • 什么是数据库池?

    我只是想了解数据库连接池的概念以及它是如何实现的 数据库联系池是一种用于保持数据库连接打开的方法 以便其他人可以重用它们 通常 打开数据库连接是一项昂贵的操作 尤其是在数据库位于远程的情况下 您必须打开网络会话 进行身份验证 检查授权等等
  • 时间戳半小时窗口内字段的平均值

    我的数据框有列名Timestamp es看起来像 Timestamp es 2015 04 01 09 07 42 31 2015 04 01 09 08 01 29 5 2015 04 01 09 15 03 18 5 2015 04 0
  • Scrapy - 持续从数据库中获取要爬取的url

    我想不断地从数据库中获取要爬行的网址 到目前为止 我成功地从基地获取了 url 但我希望我的蜘蛛继续从该基地读取 因为该表将由另一个线程填充 我有一个管道 一旦爬行 工作 就会从表中删除 url 换句话说 我想使用我的数据库作为队列 我尝试
  • 绘制点之间的所有线

    我有以下 R 代码 x lt c 0 01848598 0 08052353 0 06741172 0 11652034 y lt c 0 4177541 0 4042247 0 3964025 0 4074685 d lt data fr
  • 将 Android 应用程序从 Lite 升级到 Pro 版本时保持相同的 SQLite 数据库

    首先 我已经进行了搜索 但找不到我的问题的具体答案 所以这里是 我正在编写我的第一个 Android 应用程序 并计划拥有 Lite 版本 有限功能 和付费版本 完整功能 Lite 和 Pro 版本将使用相同的 SQLite 数据库结构 如
  • Dendextend:关于如何根据定义的组为树状图的标签着色

    我正在尝试使用一个名为 dendextend 的很棒的 R 包来绘制树状图并根据一组先前定义的组为其分支和标签着色 我已阅读您在 Stack Overflow 中的答案以及 dendextend vignette 的常见问题解答 但我仍然不
  • 在 R 中绘制 Likert 变量的堆积条形图

    假设我有一个如下所示的数据框 P Q1 Q2 1 1 4 1 2 2 3 4 3 1 1 4 其中的列告诉我哪个人相应地回答了问题 q1 q2 中的哪一个 这些问题需要按照 4 分李克特量表进行回答 例如 批准 表示 1 稍微批准 表示 2
  • 从命令行运行 R 代码 (Windows)

    我在名为 analysis r 的文件中有一些 R 代码 我希望能够从命令行 CMD 运行该文件中的代码 而无需通过 R 终端 并且我还希望能够传递参数并在我的代码中使用这些参数 例如就像下面的伪代码 C gt execute r scri
  • 为什么 dplyr filter() 不能在函数内工作(即使用变量作为列名)?

    使用 dplyr 函数对数据进行过滤 分组和变异的函数 基本管道序列在函数之外工作得很好 这就是我使用真实列名称的地方 将其放入一个函数中 其中列名称是一个变量 并且某些函数可以工作 但有些函数则不能 尤其是 dplyr filter 例如
  • 在 R 中创建虚拟变量,排除某些情况为 NA

    我的数据看起来像这样 V1 V2 A 0 B 1 C 2 D 3 E 4 F 5 G 9 我想创建一个虚拟变量R where 0 1 1 2 3 4 and NA 0 5 9 应该很简单 有人可以帮忙吗 我们可以转换V2 into a fa
  • 如何在不运行 PostgreSQL 服务器的情况下初始化 PostgreSQL 数据库

    在初始化脚本中 我想初始化 PostgreSQL 目录 但在此阶段不需要 也不希望 正在运行的 PostgreSQL 服务器 如果我只是创建集群 作为用户postgres initdb D 但是 我还需要创建 PostgreSQL 角色 创
  • 将每列的值乘以 R 中另一个 data.frame 中的权重

    我有两个data frames df and weights 代码如下 df看起来像这样 id a b d EE f 1 this 0 23421153 0 02324956 0 5457353 0 73068586 0 5642554 2
  • 如何在 SQLite 中将时间戳转换为字符串?

    我有一个表 其中存储了时间戳 以毫秒为单位 我想将这些时间戳转换为人类可读的形式 这是我的表的输出示例 SELECT date raw strftime d m Y date 1000 as string FROM my table raw
  • 在sqlite SQL语句中与order by子句结合使用limit

    下面的两条 SQL 语句总是会产生相同的结果集吗 1 SELECT FROM MyTable where Status 0 order by StartTime asc limit 10 2 SELECT FROM SELECT FROM

随机推荐