错误:列 <名称> 的类型是没有时区的时间戳,但表达式的类型是字符变化

Posted

技术标签:

【中文标题】错误:列 <名称> 的类型是没有时区的时间戳,但表达式的类型是字符变化【英文标题】:ERROR: column <name> is of type timestamp without time zone but expression is of type character varying 【发布时间】:2020-11-24 09:51:48 【问题描述】:

我正在从 MS SQL 数据库表读取 csv 文件导出并尝试将数据插入 PostgreSQL (Aurora Serverless) 数据库。当我在 PostgreSQL 数据库中创建等效表时,我使用了列类型映射,我 found online 将日期时间(MS SQL)映射到时间戳(3)(PostgreSQL)类型。但是,当我尝试将记录插入 Postgres db 时,我收到了该错误:

Batch entry 0 INSERT INTO my_table VALUES (\'10000002\', \'2020-11-22 00:00:00\')\nRETURNING * was aborted: 
ERROR: column "Date" is of type timestamp without time zone but expression is of type character varying\n 
Hint: You will need to rewrite or cast the expression.\n  Position: 37  Call getNextException to see other errors in the batch.

我的 MS SQL 表架构:

ID: varchar(20)
Date: datetime

csv 文件包含:

10000002, 2020-11-22 00:00:00
10000003, 2020-11-22 00:00:00
...

PostgreSQL 表架构/创建语句:

CREATE table my_table
(
    "ID"                      varchar(20)  not null,
    "Date"                  timestamp(3)
);

在错误消息中,提示说我可能必须转换表达式,但我不确定我应该如何做,或者这是否是我情况下的最佳解决方案。

我正在使用以下脚本从 csv 文件加载数据并将其推送到 PostgreSQL 数据库:

import boto3
import csv
rds_client = boto3.client('rds-data')

def batch_execute_statement(sql, sql_parameter_sets, transaction_id=None):
    parameters = 
        'secretArn': db_credentials_secrets_store_arn,
        'database': database_name,
        'resourceArn': db_cluster_arn,
        'sql': sql,
        'parameterSets': sql_parameter_sets
    
    if transaction_id is not None:
        parameters['transactionId'] = transaction_id
    response = rds_client.batch_execute_statement(**parameters)
    return response

transaction = rds_client.begin_transaction(
    secretArn=db_credentials_secrets_store_arn,
    resourceArn=db_cluster_arn,
    database=database_name)


sql = "INSERT INTO rigs_latest VALUES (:ID, :Date;"
parameter_set = []


with open('data.csv', 'r') as file:
    reader = csv.DictReader(file, delimiter=',')
    for row in reader:
        entry = [
            'name': 'ID', 'value': 'stringValue': row['ID'],
            'name': 'Date', 'value': 'stringValue': row['Date']
        ]
        parameter_set.append(entry)

response = batch_execute_statement(
    sql, parameter_set, transaction['transactionId'])

更新

如果我使用查询编辑器插入一条记录,例如insert into rigs_latest values (10000002, '2020-11-22 00:00:00');,它可以正常工作

这表明代码本身有问题

【问题讨论】:

如何将数据加载到表中?请向我们展示您的代码的相关部分。 我应该这样做的,抱歉。我用我正在使用的脚本更新了我的问题 【参考方案1】:

花了一些时间研究之后,我发现我们可以在parameter_set 中为每个entry 指定一个typeHint。根据documentationtypeHint允许我们指定参数是时间TIMESTAMP像这样:

...
    entry = [
        'name': 'ID', 'value': 'stringValue': row['ID'],
        'name': 'Date','typeHint': 'TIMESTAMP', 'value': 'stringValue': row['Date']
    ]
    parameter_set.append(entry)
...

我想这有助于解释器确定我们希望 Date 参数的类型为 TIMESTAMP

【讨论】:

我在一些 GoLang 代码中发现了这个问题。我使用 Name: aws.String("submitted"), TypeHint: aws.String("TIMESTAMP"), Value: &rdsdataservice.Field StringValue: aws.String(submitted), , ,

以上是关于错误:列 <名称> 的类型是没有时区的时间戳,但表达式的类型是字符变化的主要内容,如果未能解决你的问题,请参考以下文章

postgreSQL 将列数据类型更改为没有时区的时间戳

使用 Spring Data 的 postgres 中的时间戳出错:列 $COLUMN_NAME 是没有时区的时间戳类型,但表达式是 bytea 类型

Postgresql 在没有时区的情况下将秒转换为时间

XSL - 我想在我的数据中替换所有出现的错误时区

表的优化与列类型选择

DateTime<Utc> 编译但不是 DateTime<Local> 查询表,其列定义为带时区的时间戳