【问题标题】:storing a vector in a relational database将向量存储在关系数据库中
【发布时间】:2018-06-18 06:15:02
【问题描述】:

在我的计算中,我得到了一些存储在向量中的结果。因为这些计算是重复执行的,所以我会在我的数据库中存储一些向量。 在我的数据库表 data_storage 中,每一行都应该存储一个结果向量。

直到现在我发现我的表中需要一个 BLOB 变量,并且向量必须按照Storing R Objects in a relational database 中的说明进行序列化。 在这个提到的来源上,David Josipovic 的答案似乎非常适合我,但我无法正确编码。查看我的代码中的数据输入...

EDIT_1:使用dbGetQuerydbExecute()dbBind() 时会出现错误消息。序列化错误(res_1.v):缺少连接参数(没有默认值)。

对我来说,重要的是要知道如何在数据库中获取结果向量以及如何将它们取出。 所以我希望你能帮助我。

提前非常感谢!

我的代码:

# needed packages for this script 
# install.packages("sqldf")  # install this package if necessary
library(sqldf)

# connection to the database
db=dbConnect(SQLite(), ":memory:")

# creation of the database table
dbSendQuery(conn = db,
    "CREATE TABLE IF NOT EXISTS data_storage
    (ID INTEGER,
    data BLOB,
    PRIMARY KEY (ID))")

# calculations
# ....

# the first result vector
res_1.v=seq(from=1,to=10,by=1)

# the second result vector
res_2.v=seq(from=5,to=7,by=0.1)

# filling the data_storage table with the result vectors (in two rows)
### here an error occures
dbGetQuery(db, 'INSERT INTO data_storage VALUES (1,:blob)', params =  list(blob = list(serialize(res_1.v))))  # the first row with res_1.v
dbGetQuery(db, 'INSERT INTO data_storage VALUES (2,:blob)', params = list(blob = list(serialize(res_2.v))))  # the second row with res_2.v

# getting the serialized result vector out of the database
# and converting them again to the result vector res_1.v respectively res_2.v
#######################################
### the still missing code sequence ###
#######################################

# close the connection
dbDisconnect(db) 

【问题讨论】:

  • 如果您尝试插入,您可能需要dbExecute() 而不是dbGetQuery()
  • @Marius 和 dbExecute() 也会发生错误。连接丢失并在括号中“没有默认值”
  • @tueftla 如果你想使用语句,那么我认为你需要dbSendStatementdbExecute 用于不带参数的直接 DML 命令。

标签: r sqlite serialization rsqlite


【解决方案1】:

也许你的语法有问题。这个 RSQLite documentation page 使用 dbSendStatement 来构建一个准备好的语句来执行 DML 命令:

rs <- dbSendStatement(db, 'INSERT INTO data_storage VALUES (1, :blob)')
dbBind(rs, param = list(blob = serialize(res_1.v)))
dbGetRowsAffected(rs)
dbClearResult(rs)

此答案假定 API 将正确知道如何将 BLOB 绑定到语句中。

【讨论】:

  • dbBind() 也会导致错误。连接丢失并在括号中“没有默认值”
  • 那么你的数据库连接对象可能有问题。
  • 在我的帖子中输入代码时,一切正常,直到我想存储结果向量。使用dbListFields(db,"data_storage") 会显示两列 ID 和数据...
  • @tueftla 这并不意味着没有问题。在您实际使用它之前,您可能不会发现连接有问题。但是,我不是 RSQLite 专家,只是想指出我认为使用 DML 准备语句的正确语法。
【解决方案2】:

感谢两位评论者 Marius 和 Tim Biegeleisen,经过一段时间的反复试验,我找到了解决方案...

在第一部分的代码没有任何改变

# needed packages for this script 
# install.packages("sqldf")  # install this package if necessary
library(sqldf)

# connection to the database
db=dbConnect(SQLite(), ":memory:")

# creation of the database table
dbSendQuery(conn = db,
    "CREATE TABLE IF NOT EXISTS data_storage
    (ID INTEGER,
    data BLOB,
    PRIMARY KEY (ID))")

# calculations
# ....

# the first result vector
res_1.v=seq(from=1,to=10,by=1)

# the second result vector
res_2.v=seq(from=5,to=7,by=0.1)

现在是代码的第二部分,我在其中更改、添加并完全附加了一些代码行...

# filling the data_storage table with the result vectors (in two rows)
### here you can/must use dbExecute() as suggested by Marius
### and in list(serialize(res_1.v,NULL)) the connection NULL is important
dbExecute(db, 'INSERT INTO data_storage VALUES (1,:blob)', params = list(blob = list(serialize(res_1.v,NULL))))  # the first row with res_1.v
dbExecute(db, 'INSERT INTO data_storage VALUES (2,:blob)', params = list(blob = list(serialize(res_2.v,NULL))))  # the second row with res_2.v

# reading out the content of table data_storage
dbReadTable(db,"data_storage")

# It's nearly the same - reading out the content of data_storage
dbGetQuery(db,'SELECT * FROM data_storage')
dbGetQuery(db,'SELECT * FROM data_storage')[,1]  # the content of the first column
dbGetQuery(db,'SELECT * FROM data_storage')[,2]  # the content of the second column - this is a BLOB

# get the result vector with its original entries
### and unlist() the BLOB entry
### and finally unserialize the unlisted BLOB entry
step_1=unlist(dbGetQuery(db,'SELECT * FROM data_storage')[1,2])  # here you must adjust the row index
step_2=unserialize(step_1)

# for control of equality
### step_2 is the converted res_1.v to BLOB and the reconverted
### so the outcome of identical() is TRUE
identical(res_1.v,step_2)

# close the connection
dbDisconnect(db)

【讨论】:

    猜你喜欢
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-15
    • 2012-10-24
    相关资源
    最近更新 更多