2016-04-16 2 views
0

Я новичок в PostgreSQL, и я пытаюсь использовать R для записи таблицы в PostgreSQL. См. Код R ниже; сделать некоторые воспроизводимый кадр данных первым:R не удается записать таблицу в PostgreSQL через rPostgreSQL

> 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 

затем создает соединение:

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) 

Затем я создаю таблицу в PostgreSQL БД:

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; 

Наконец выполнить код таблицы записи и получил погрешность:

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" 

Это должно быть не так сложно, но я искал решение какое-то время, но напрасно. И на самом деле я использовал набор данных «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 

вставили 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; 

Заранее спасибо за любые предложения и идеи.

+0

@Parfait: Привет, это фактор в кадре данных. Благодарю. – Samoth

ответ

3

Обратите внимание на тип данных из двух столбцов таблицы:

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

Теперь давайте посмотрим на данные, которые вы пытаетесь вставить:

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 

Теперь сообщение об ошибке:

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" 

character(N) Тип данных в PostgreSQL - это строковый тип фиксированной длины. Каждое значение в этом столбце должно быть строкой символов с длиной N. Для character(1) это означает, что каждое значение должно содержать один символ.

Значение 'ABC' - это строка длиной 3. Она слишком длинна для типа данных character(1).

Возможно, вы путаете векторный тип символа R с типом символа SQL. В R каждый элемент символьного вектора представляет собой строку переменной длины. Как ни странно, вы можете построить вектор символов в R с синтаксисом character(N), где N - количество строковых элементов переменной длины в результирующем векторе. В SQL вы можете рассматривать столбец как вектор, но типы данных всегда относятся к скалярному типу одного значения ячейки. N в синтаксисе SQL character(N) относится к числу символов в каждой строке.

Причина ваш mtcars тест работал потому, что только строка столбец в этой таблице carname, который имеет тип character varying данных без спецификации длины. Из PostgreSQL documentation:

If character varying is used without length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension.

Таким образом, вы можете решить эту проблему с помощью character varying (или его более короткое имя varchar) для этих двух столбцов.Вы можете опустить спецификацию длины так же, как в схеме mtcars, или если вам известно о пределе договорной длины для значений этих столбцов, вы можете указать varchar(N), где N - предел длины. Кроме того, если значения Department всегда имеют длину 3 символа, у вас есть возможность перейти с char(3) для типа фиксированной длины.

Резюме:

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 
Смежные вопросы