【发布时间】:2011-10-28 14:29:39
【问题描述】:
我正在尝试将长 xml 字符串作为文本批量插入到 postgresql 9.1 数据库中。我正在使用 Python 3.2 和 pyscopg2。我将 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 上搜索了答案,但没有找到解决方案:
【问题讨论】:
-
是什么让你如此确定你的大文本数据不包含
$$,这样你就不必逃避它? -
如果我的理解是正确的,那么您不必担心字符串中的任何 $。引用 Postgresql 文档:4.1.2.4。美元引用的字符串常量 - 请注意,在美元引用的字符串中,可以使用单引号而无需转义。实际上,美元引号字符串中的任何字符都不会被转义:字符串内容总是按字面意思书写。反斜杠不是特殊的,美元符号也不是特殊的,除非它们是与开始标签匹配的序列的一部分。
-
您应该担心。请参阅您引用的最后一句话。
-
你是对的,但我仍然想知道处理这个问题的最佳方法,我是否需要解析完整的字符串并在必要时转义而不使用 $$ 语法。我不介意检查它们的开始标签,但希望避免解析每个字符串中的所有文本。在我们的特殊情况下,我们正在创建 xml 并插入值,因此我可以控制 xml 但不能控制值。必须有一个标准的方法来做到这一点???
-
执行此操作的标准方法是让驱动程序处理它,就像在您的第一个代码示例中一样。
标签: python postgresql psycopg2