使用Python将大文本数据插入Postgres

2 投票
1 回答
2154 浏览
提问于 2025-04-17 05:11

我正在尝试将长的 XML 字符串作为文本批量插入到 PostgreSQL 9.1 数据库中。我使用的是 Python 3.2 和 psycopg2 库。我把 XML 字符串用 $$ 包起来,并在查询字符串中使用了一个命名变量。例如:

query = "insert into cms_object_metadata (cms_object_id, cms_object_metadata_data, cms_object_metadata_type_id, \
         cms_object_metadata_status_id) values ((select id from cms_objects where cms_object_ident = %(objIdent)s), \
         $$%(objMetaString)s$$, (select id from cms_object_metadata_types where cms_object_metadata_type_name = 'PDAT'), \
         (select id from cms_object_metadata_status where cms_object_metadata_status_name = 'active'))"

接着,我构建了一个字典对象,如下所示:

dataDict = {'objIdent':objIdent, 'objMetaString':objMetaString}

传入 objIdent 和 objMetaString 的值。我用以下代码进行插入:

dbCursor.execute(query, dataDict)

当我将 objMetaString 的值插入到数据库时,字符串周围会有单引号。如果我把值直接拼接到查询字符串中并执行插入,而不使用命名变量,就不会有单引号。例如:

query = "insert into cms_object_metadata (cms_object_id, cms_object_metadata_data, cms_object_metadata_type_id, \
         cms_object_metadata_status_id) values ((select id from cms_objects where cms_object_ident = %s), \
         $$%s$$, (select id from cms_object_metadata_types where cms_object_metadata_type_name = 'PDAT'), \
         (select id from cms_object_metadata_status where cms_object_metadata_status_name = 'active'))" % (objIdent, objMetaString)

然后是插入的代码:

dbCursor.execute(query)

我想问的是,如何使用命名变量和 $$ 来批量插入大文本数据。如果可以的话,我不想对这个字符串进行预处理或后处理,因为它们可能很大,并且可能包含未知数量的单引号或其他需要分隔的符号。我已经阅读了以下文档,并在 StackOverflow 上搜索了答案,但还没有找到解决方案:

1 个回答

1

总结一下评论的内容。你需要这样做:

query = "insert into cms_object_metadata (cms_object_id, cms_object_metadata_data, cms_object_metadata_type_id, \
         cms_object_metadata_status_id) values ((select id from cms_objects where cms_object_ident = %(objIdent)s), \
         %(objMetaString)s, (select id from cms_object_metadata_types where cms_object_metadata_type_name = 'PDAT'), \
         (select id from cms_object_metadata_status where cms_object_metadata_status_name = 'active'))"

dataDict = {'objIdent':objIdent, 'objMetaString':objMetaString}

dbCursor.execute(query, dataDict)

不要在你的查询中给 %(objMetaString)s 这个占位符加上引号。是否需要加引号是数据库驱动程序的事情。

撰写回答