我正在使用psycopg2创建一个表分区,并将一些行插入到这个新创建的分区中。表是在日期类型列上分区的。
Psycopg2代码:
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()的格式化输出:
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);收到的错误:
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编辑器中执行以下语句是成功的:
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正确格式化查询,有什么想法吗?
发布于 2021-10-01 15:58:16
跟进@LaurenzAlbe评论:
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值。每个文字值必须是对相应分区键列的类型强制的数值常量,或者是该类型的有效输入的字符串文本。
https://stackoverflow.com/questions/69404439
复制相似问题