简体   繁体   English

R无法通过rPostgreSQL将表写入PostgreSQL

[英]R fails to write table to PostgreSQL via rPostgreSQL

I am new to PostgreSQL and I'm trying to use R to write table to PostgreSQL. 我是PostgreSQL的新手,我正在尝试使用R将表写入PostgreSQL。 See the R code below; 见下面的R代码; make some reproducible data frame first: 首先制作一些可重现的数据框:

> Time<-c('201512', '201511', '201510')
> Department<-c('ABC', 'BCA', 'NBA')
> Pro_Type<-c('standard', 'maintain', 'sustaining')
> Man_month<-c('111.4', '124.1', '232.1')
> ID<-c('1','2', '3')
> melt_short<-data.frame(Time, Department, Pro_Type, Man_month, ID)
> melt_short
   Time  Department   Pro_Type Man_month ID
1 201512        ABC   standard     111.4  1
2 201511        BCA   maintain     124.1  2
3 201510        NBA sustaining     232.1  3

then creates the connection: 然后创建连接:

 require("RPostgreSQL")

# loads the PostgreSQL driver
  drv <- dbDriver("PostgreSQL")
# creates a connection to the postgres database
  con <- dbConnect(drv, dbname = "XXX",
             host = "XXX.XX.XX.XXX", port = 5432,
             user = "postgres", password = XXXXXX)

then I create a table in PostgreSQL DB: 然后我在PostgreSQL DB中创建一个表:

 CREATE TABLE dms_melt
(
  "Time" numeric,
  "Department" character(1),
  "Pro_type" character(1),
  "Man_month" numeric,
  "ID" numeric NOT NULL,
  CONSTRAINT dms_melt_pkey PRIMARY KEY ("ID")
)
WITH (
  OIDS=FALSE
);
 ALTER TABLE dms_melt
 OWNER TO postgres;

Finally execute the write table code and got the error: 最后执行写表代码并得到错误:

dbWriteTable(con, "dms_melt", value = melt_short, append = T,row.names=F)

Error in postgresqlgetResult(new.con) : 
RS-DBI driver: (could not Retrieve the result : ERROR:  value too long for   
type character(1) CONTEXT:  COPY dms_melt, line 1, column Department: "ABC"

It should be not so hard but I've been searching for solution for a while but in vain. 它应该不是那么难,但我一直在寻找解决方案一段时间,但徒劳无功。 And actually I've used the "mtcars" data set to write table and with no problem. 实际上我已经使用“mtcars”数据集写表并没有问题。

data(mtcars)
df <- data.frame(carname = rownames(mtcars), 
                 mtcars, 
                 row.names = NULL)
df$carname <- as.character(df$carname)

dbWriteTable(con, "cartable", 
             value = df, append = TRUE, row.names = FALSE)
[1] TRUE

inserted the PostgreSQL which I created as: 插入我创建的PostgreSQL:

CREATE TABLE cartable
(
  carname character varying,
  mpg numeric(3,1),
  cyl numeric(1,0),
  disp numeric(4,1),
  hp numeric(3,0),
  drat numeric(3,2),
  wt numeric(4,3),
  qsec numeric(4,2),
  vs numeric(1,0),
  am numeric(1,0),
  gear numeric(1,0),
  carb numeric(1,0)
 )
 WITH (
  OIDS=FALSE
 );
 ALTER TABLE cartable
 OWNER TO postgres;

Thanks in advance for any suggestions and ideas. 提前感谢任何建议和想法。

Pay attention to the data type of the following two table columns: 请注意以下两个表列的数据类型:

...
"Department" character(1),
"Pro_type" character(1),
...

Now let's look at the data you're trying to insert: 现在让我们看一下您尝试插入的数据:

   Time  Department   Pro_Type Man_month ID
1 201512        ABC   standard     111.4  1
2 201511        BCA   maintain     124.1  2
3 201510        NBA sustaining     232.1  3

Now the error message: 现在出现错误信息:

Error in postgresqlgetResult(new.con) :
RS-DBI driver: (could not Retrieve the result : ERROR:  value too long for
type character(1) CONTEXT:  COPY dms_melt, line 1, column Department: "ABC"

The character(N) data type in PostgreSQL is a fixed-length string type. PostgreSQL中的character(N)数据类型是固定长度的字符串类型。 Every value in that column must be a string of characters with length N. For character(1) , this means every value must comprise a single character. 该列中的每个值必须是长度为N的字符串。对于character(1) ,这意味着每个值必须包含单个字符。

The value 'ABC' is a string with length 3. It is too long for the character(1) data type. 'ABC'是长度为3的字符串。对于character(1)数据类型,它太长。

You may be confusing the R character vector type with the SQL character type. 您可能会将R字符向量类型与SQL字符类型混淆。 In R, each element of a character vector is a variable length string. 在R中,字符向量的每个元素是可变长度字符串。 Ironically, you can construct a character vector in R with the syntax character(N) where N is the number of variable-length string elements in the resulting vector. 具有讽刺意味的是,您可以使用语法character(N)在R中构造字符向量,其中N是结果向量中可变长度字符串元素的数量。 In SQL, you can view a column as being a vector, but data types always refer to the scalar type of a single cell value. 在SQL中,您可以将列视为向量,但数据类型始终引用单个单元格值的标量类型。 The N in the SQL syntax character(N) refers to number of characters in each string. SQL语法character(N)每个字符串中的字符数。

The reason your mtcars test worked is because the only string column in that table is carname which has data type character varying with no length specification. 您的mtcars测试工作的原因是因为该表中唯一的字符串列是carname ,其数据类型character varying长度规范而character varying From the PostgreSQL documentation : PostgreSQL文档

If character varying is used without length specifier, the type accepts strings of any size. 如果在没有长度说明符的情况下使用字符变化,则该类型接受任何大小的字符串。 The latter is a PostgreSQL extension. 后者是PostgreSQL扩展。

So, you can solve the problem by using character varying (or its more concise name varchar ) for these two columns. 因此,您可以通过为这两列使用character varying (或更简洁的名称varchar )来解决问题。 You can omit the length specification just as in the mtcars schema, or if you are aware of a contractual length limit on the values of those columns you can specify varchar(N) where N is the length limit. 您可以像在mtcars模式中一样省略长度规范,或者如果您知道这些列的值的合同长度限制,则可以指定varchar(N) ,其中N是长度限制。 Also, if Department values are always 3 characters long, you have the option of going with char(3) for a fixed-length type. 此外,如果Department值总是3个字符长,您可以选择使用char(3)作为固定长度类型。

Summary: 摘要:

SQL
==========

character(N)            fixed-length strings of length N
char(N)                 alias for character(N)
character               alias for character(1)
char                    alias for character(1)
character varying(N)    variable-length strings of maximum length N
varchar(N)              alias for character varying(N)
character varying       variable-length strings of unlimited length
varchar                 alias for character varying

R
==========

character(N)            vector of length N of variable-length strings

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM