【问题标题】:How to save R data frame to AWS redshift when there are more than 256 characters?超过 256 个字符时如何将 R 数据帧保存到 AWS redshift?
【发布时间】:2026-01-29 23:15:01
【问题描述】:

我正在尝试使用使用 dplyr 的 src_postgres 函数建立的 postgres 连接将数据框保存到 AWS redshift 数据库。正如您在下面看到的,数据框中有一列超过 256 个字符(有些甚至更多)。当我尝试将此数据框保存到 redshift 时,我在使用 dplyr 的 copy_to 函数时收到以下错误。无论如何我可以增加字符数的限制,以便我可以将此数据框保存到 AWS redshift 上,或者其他人对如何将我的数据框保存到 redshift 有任何建议吗?谢谢你。

> nchar(df$text)
[1] 598

> copy_to(conn_dplyr, df, TableName, temporary = FALSE)
Error in postgresqlExecStatement(conn, statement, ...) : 
RS-DBI driver: (could not Retrieve the result : ERROR:  value too long for    type character varying(256)
)

【问题讨论】:

    标签: r postgresql dplyr amazon-redshift


    【解决方案1】:

    这是因为 Redshift 不支持 Text 数据类型。当您将任何列声明为 Text 时,Redshift 在内部将其存储为 Varchar(255)。 相反,将您的列/变量更改为 varchar(1000) (长度取决于传入的预期值)。

    【讨论】:

    • 感谢圣骑士!我现在明白了,但我仍然对如何更改 varchar(1000) 感到困惑?在我尝试将其写入红移数据库之前,您能帮我解决一下改变它的语法吗?感谢您的帮助。
    • 不确定我是否理解您的要求,但我可以想象两种情况 1. 如何更改红移列大小:ALTER TABLE t1 ADD COLUMN new_column (correct_column_definition i>);更新 t1 SET new_column = 列; ALTER TABLE t1 DROP COLUMN 列; ALTER TABLE t1 RENAME COLUMN new_column TO 列; *.com/questions/17101918/… 2. 如何在你的代码中改变它:不确定 dplyr 但你必须有一个 cast/convert 函数。使用它将您的文本转换为 varchar(1000),然后将其传递给 Redshift 函数。
    【解决方案2】:

    我最近遇到了一个非常相似的问题,并找到了一些解决方法,虽然不是很优雅,但它确实有效

    getColumnClasses <- function(df) {
      return(data.frame(lapply(df[1, ], class)))
    }
    

    然后添加了一个简单的查找函数:

    rClassToRedshiftType <- function(class) {
       switch(class,
         factor = {
           return('VARCHAR(256)')
         },
         character = {
           return('VARCHAR(65535)')
         },
         logical = {
           return('boolean')
         },
         numeric = {
           return('float')
         },
         integer = {
           return('int')
         }
       )
       return('timestamp')
    }
    
    getRedshiftTypesForDataFrame <- function(df) {
      return(
        apply(
          getColumnClasses(df), 2,
          FUN = rClassToRedshiftType
        )
      )
    }
    

    最后,你可以使用参数types调用copy_to

      dplyr::copy_to(
        connection,
        df, table.name,
        temporary = FALSE, types = getRedshiftTypesForDataFrame(df)
      )
    

    显然,如果您事先知道列,您可以手动定义types 向量

    【讨论】: