2012-07-06 99 views
2

我有一个脚本为我创建了一个特定的INSERT SQL语句。如何逃避'在一个字符串内?

对于postgresql我需要包装值插入两个单引号内。

不幸的是一些要插入的值字符串还包含单引号,我需要自动转义它们。

for line in f: 
    out.write('(\'' + line[:2] + '\', \'' + line[3:-1] + '\'),\n') 

我怎样才能确保内部line[3:-1]任何单引号(例如')自动逃跑?

谢谢,

UPDATE:

例如行

CI|Cote D'ivoire 

由于失败'

更新2:

我不能值使用双引号,例如

INSERT INTO "App_country" (country_code, country_name) VALUES ("AF", "Afghanistan")

我得到的错误信息:ERROR: column "AF" does not exist

然而,这工作得很好:

INSERT INTO "App_country" (country_code, country_name) VALUES ('AF', 'Afghanistan')

+1

你可能只是想使用DBAPI方法,而不是,它已经逃出不安全的字符。 – Keith 2012-07-06 22:55:08

+0

在重新阅读您的问题时,我不确定我是否有正确的问题。你能提供'line'的内容吗? – Levon 2012-07-06 22:59:46

+0

@Keith任何指针,我怎么用DBAPI做到这一点? – Houman 2012-07-06 23:08:34

回答

2

PEP-249中所述,DBPI是通用的inter面对各种数据库。不同的数据库存在不同的实现。对于postgres有psycopg。从文档:

cur.execute(
...  """INSERT INTO some_table (an_int, a_date, a_string) 
...   VALUES (%s, %s, %s);""", 
...  (10, datetime.date(2005, 11, 18), "O'Reilly")) 

你简单地传递你的参数在一个元组中。底层库为你逃脱。这比试图推出自己的产品更安全,更简单。

0

不知道,如果有一些SQL相关的限制,但你总是使用双引号围绕包含单引号的字符串。

EG。

print "That's all Folks!" 

或单引号包围双引号:

print 'The name of the file is "rosebud".' 
+0

OP,请记住反斜杠插值会发生在除Python以外的所有原始字符串中! – 2012-07-06 22:51:10

+0

不幸的是,有一个限制:INSERT INTO“App_country”(country_code,country_name)值 (“AF”,“Afghanistan”)'给出错误'ERROR:column“AF”不存在'PostgreSQL似乎没有喜欢它。 – Houman 2012-07-06 22:59:49

+0

-1 OP将可变文本*数据*插入到SQL数据库的列中。 Python字符串常量的形成规则是非常不相关的。 – 2012-07-07 05:57:56

0

对于一个完整的解决方案TOADD转义字符的字符串,使用:

re.escape(string) 
>>> re.escape('\ a.*$') 
'\\\\\\ a\\.\\*\\$' 

更多,请参阅:http://docs.python.org/library/re.html

+0

这不是一个正规的表达式,他试图逃跑。 – Ryan 2012-07-06 23:57:17

1

SQL标准的方式来逃避报价是双击它:

'This won''t be a problem.' 

因此,与两个单引号替换每个引号(和Python中使用双引号来保持理智):

out.write("('" + line[:2] + "', '" + line[3:-1].replace("'", "''") + "'),\n") 
+0

-1小奈德表? – 2012-07-07 05:52:39

2

切勿对DML使用生成的滚动自己的转义。如Keith所述,使用适当的DBAPI。为了确保各种来源的逃逸和类型转换几乎可以透明地进行,工作将会进行。如果您使用的是DDL,例如CREATE TABLE whatever (...) - 如果您信任自己的数据源,则可以更轻松一些。使用例如所示数据

import sqlite3 

text = "CI|Cote D'ivoire" # had to been escaped as it's a string literal, but from another data source - possibly not... 

code, name = text.split('|', 1) 

db = sqlite3.connect(':memory:') 
db.execute('create table something(code, name)') 
db.execute('insert into something(code, name) values(?, ?)', (code, name)) 

for row in db.execute('select * from something'): 
    print row 
# (u'CI', u"Cote D'ivoire") 
+0

+1。给了我一些想法谢谢。我发现Keith的解决方案更容易,因为我已经psycopg2。 – Houman 2012-07-07 08:17:04