psycopg2中与mysqldb.escape_string相当的是什么?

33

我正在使用Python中的psycopg2向Postgres字符字段传递一些值。其中一些字符串值包含句点、斜杠、引号等。

对于MySQL,我只需使用转义字符串就可以:

MySQLdb.escape_string(my_string)

psycopg2 有没有相应的替代品?

5个回答

42

转义是自动的,你只需要调用:

cursor.execute("query with params %s %s", ("param1", "pa'ram2"))

(请注意Python的%运算符没有使用),因此值将被正确转义。

您可以使用extensions.adapt(var)手动转义变量,但这样做容易出错,并且无法考虑连接编码:它应该在常规客户端代码中使用。


2
adapt() 类似,你可以显式地使用特定的适配协议对象; 例如 QuotedString(r"O'Reilly").getquoted()参见文档 - rakslice
我的JSON列不会自动转义...有什么方法可以做到这一点吗? - Alex
@Alex 搜索 "psycopg json",会带您到 psycopg json 适配器 页面。 - piro
注意:不要在%s周围加上撇号,即它不是'%s',而只是%s。 - dasWesen
除了查询参数之外,还要查看来自 psycopg2.sql 模块的 SQL 组成。例如,您可以在对 psycopg2.sql.SQL() 的调用中使用 psycopg2.sql.Identifier 来正确传递表名。 - dr_dronych

12

4

如果查询参数不足以满足需求,需要自行转义字符串,您可以使用Postgres转义字符串常量并结合Python的repr(因为Python转义非ASCII和Unicode字符的规则与Postgres相同):

def postgres_escape_string(s):
   if not isinstance(s, basestring):
       raise TypeError("%r must be a str or unicode" %(s, ))
   escaped = repr(s)
   if isinstance(s, unicode):
       assert escaped[:1] == 'u'
       escaped = escaped[1:]
   if escaped[:1] == '"':
       escaped = escaped.replace("'", "\\'")
   elif escaped[:1] != "'":
       raise AssertionError("unexpected repr: %s", escaped)
   return "E'%s'" %(escaped[1:-1], )

1

psycopg2 似乎在 2.7 版本中添加了一个方法: http://initd.org/psycopg/docs/extensions.html#psycopg2.extensions.quote_ident

from psycopg2.extensions import quote_ident

with psycopg2.connect(<db config>) as conn:
    with conn.cursor() as curs:
        ident = quote_ident('foo', curs)

如果您遇到以下错误: TypeError: argument 2 must be a connection or a cursor,请尝试以下两种方法之一:
ident = quote_ident('foo', curs.cursor)

# or

ident = quote_ident('food', curs.__wrapper__)


请注意此函数的讨论:https://stackoverflow.com/q/62396036/997940 - Yoav Feuerstein

0

Psycopg2没有这样的方法。 它有一个 扩展,用于将Python值适应为ISQLQuote对象,并且这些对象具有getquoted()方法以返回与PostgreSQL兼容的值。

请参阅此博客以获取如何使用它的示例:

使用psycopg2在SQL语句中引用绑定值

更新2019-03-03:更改链接到archive.org,因为经过九年,原始链接已不再可用。


5
请注意,那个人是错的:他想要做的可以使用 mogrify() 方法实现(http://initd.org/psycopg/docs/cursor.html#cursor.mogrify)。 - piro
请注意,mogrify和execute都不处理转义表名,只处理参数。 - a1an
@a1an,说得好。我从未遇到过任何语言中的框架或API可以逃避表名。你呢? - Bill Karwin
很遗憾,我看到的最好的解决方案是使用参数化的选择查询来获取数据库目录中的“干净”表名。不幸的是,这种方法在CREATE语句中不起作用。后者几乎永远不会出现,但是在SOA中,服务可能会接受要创建的表的名称作为参数,谁知道呢? - a1an
getquoted()无法处理Unicode表情符号字符串。UnicodeEncodeError: 'latin-1'编解码器无法在位置0编码字符'\U0001f4d8':该值不在256的范围内。 - sudo
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接