首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >心态2/PostgreSQL 11.9:在执行字符串->日期类型强制转换时出现或接近"::“的语法错误

心态2/PostgreSQL 11.9:在执行字符串->日期类型强制转换时出现或接近"::“的语法错误
EN

Stack Overflow用户
提问于 2021-10-01 10:33:47
回答 1查看 452关注 0票数 1

我正在使用psycopg2创建一个表分区,并将一些行插入到这个新创建的分区中。表是在日期类型列上分区的。

Psycopg2代码:

代码语言:javascript
复制
conn = connect_db()
cursor = conn.cursor()
sysdate = datetime.now().date()
sysdate_str = sysdate.strftime('%Y%m%d')
schema_name = "schema_name"
table_name = "transaction_log"

# Add partition if not exists for current day
sql_add_partition = sql.SQL("""
    CREATE TABLE IF NOT EXISTS {table_partition}
    PARTITION of {table}
    FOR VALUES FROM (%(sysdate)s) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name), table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'))
print(cursor.mogrify(sql_add_partition, {'sysdate': dt.date(2015,6,30)}))
cursor.execute(sql_add_partition, {'sysdate': sysdate})

Cursor.mogrify()的格式化输出:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
PARTITION of "schema_name"."transaction_log"
FOR VALUES FROM ('2021-10-01'::date) TO (maxvalue);

收到的错误:

代码语言:javascript
复制
ERROR:  syntax error at or near "::"
LINE 3: for values FROM ('2021-10-01'::date) TO (maxvalue);

有趣的是,psycopg2似乎试图使用":: date“语法将字符串'2021-10-01‘转换为date对象,而根据postgreSQL文档,这似乎是有效的(尽管在文档中没有给出明确的示例),但是使用pyscopg2和postgreSQL查询编辑器执行语句会产生这个语法错误。但是,在postgreSQL SQL编辑器中执行以下语句是成功的:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
PARTITION of "schema_name"."transaction_log"
FOR VALUES FROM ('2021-10-01') TO (maxvalue);

对于如何使psycopg2正确格式化查询,有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-01 15:58:16

跟进@LaurenzAlbe评论:

代码语言:javascript
复制
sql_add_partition = sql.SQL("""
    CREATE TABLE IF NOT EXISTS {table_partition}
    PARTITION of {table}
    FOR VALUES FROM (%(sysdate)s) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name), table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'))
print(cursor.mogrify(sql_add_partition, {'sysdate': '2021-10-01'}))

#OR

sql_add_partition = sql.SQL("""
    CREATE TABLE IF NOT EXISTS {table_partition}
    PARTITION of {table}
    FOR VALUES FROM ({sysdate}) TO (maxvalue);
""").format(table = sql.Identifier(schema_name, table_name), 
table_partition = sql.Identifier(schema_name, f'{table_name}_{sysdate_str}'),
sysdate=sql.Literal('2021-10-01'))
print(cursor.mogrify(sql_add_partition))

#Formatted as

CREATE TABLE IF NOT EXISTS "schema_name"."transaction_log_20211001"
    PARTITION of "schema_name"."transaction_log"
    FOR VALUES FROM ('2021-10-01') TO (maxvalue);

将日期作为文字值传入,而不是日期对象。psycopg2会自动调整date(time)对象到Postgres日期/时间戳类型(日期时间适应),这就是让您头疼的地方。

更新

根据我的评论,它需要是文字的原因在这里解释了创建表

partition_bound_spec中指定的每个值都是文字值、NULL值、MINVALUE值或MAXVALUE值。每个文字值必须是对相应分区键列的类型强制的数值常量,或者是该类型的有效输入的字符串文本。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69404439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档