问题描述
我正在尝试将 R 中的新列追加或绑定到 postgresql 表。所以,我在 postgresql 表中创建了一个新列,我想在其中放置我的数据框列,即
ALTER TABLE schema.table
ADD COLUMN newcolumn "char";
library(RPostgres)
library(tidyverse)
library(rpostgis)
# SQL CONNECTION
fun_connect<-function(){dbConnect(RPostgres::Postgres(),dbname = 'mydb',host = 'localhost',# i.e. 'ec2-54-83-201-96.compute-1.amazonaws.com'
port = 5432,# or any other port specified by your DBA
user = 'postgres',password = 'secretpass'}
conn <- fun_connect()
mytable<-tbl(conn,"mydb")
# MY data frame
a<-data.frame(a= c("123","231543","1232","45389","4398543"))
# Trying to append or cbind my data frame column
#First try:
copy_to(conn,a,"newcolumn")
#Second try:
RPostgreSQL::dbWriteTable(conn,"table",append=T)
So i Have the next error:
Error: COPY returned error: ERROR: el valor nulo en la columna «FIRSTcolumn» de la relación «table» viola la restricción de no nulo
DETAIL: La fila que falla contiene (null,null,1).
CONTEXT: COPY table,línea 1: «10208011005»
Third try:
pgInsert(conn,name=c("schema","table"),a)
But I get:
1 out of 1 columns of the data frame match database table columns and will be formatted for database insert.
Error : Failed to fetch row: ERROR: el valor nulo en la columna «FIRSTcolumn» de la relación «table» viola la restricción de no nulo
DETAIL: La fila que falla contiene (null,1).
Insert failed. No changes made to database.
所以我不知道如何以简单的方式将新列从 R 附加到 Postgresql。我问我是否存在类似于 cbind(df,df2)
(lol) 的东西,其中 df1 和 df2 具有相同的 nrow,但我都没有关于它是如何可能的代理
谢谢你的帮助。 问候!
解决方法
首先,您有两种不同类型的数据对象。一个是远程(不在 R 内存中)sql 表的连接,另一个是本地(在 R 内存中)数据帧。这两种类型的对象不能立即组合。这意味着这些数据类型没有简单的 cbind
等效项。
我建议首先将本地数据帧复制到 sql 数据库中。然后您将拥有两个相同类型的数据对象 - 两个 sql 表 - 您可以组合使用。
您尝试使用 copy_to
和 dbWriteTable
是一个好的开始。但是这些函数将整个 R 数据帧写入整个表,而不是作为一部分。
为了将数据帧复制到 sql 中,我使用:
DBI::dbWriteTable(
db_connection,DBI::Id(
catalog = db,schema = schema,table = sql_table_name
),r_table_name
)
您要查找的用于插入值的 sql 语法很可能是:
INSERT INTO first_table(names_of_columns1) SELECT names_of_columns2 FROM second_table;
我会在 R 中进行如下操作:
insert_into_column <- function(connection,tbl1,col1,tbl2,col2){
prep = tbl2 %>% select(col2)
query <- glue::glue("INSERT INTO {tbl1} ({col1})\n",dbplyr::sql_render(prep))
result <- DBI::dbExecute(connection,as.character(query))
}
请注意,将值插入到 sql 表的列中可能与将值插入到 R 数据框的列中不同。 sql中的表默认是不排序的,所以你的insert可能无法保证正确的顺序。