我正在研究python并尝试将数据保存到数据库中 假设我有以下代码
conn = mdb.connect(user='root', passwd='redhat', db='Data', host='localhost', charset="utf8")
ex_li = ['stri_one','stri_two','stri_three','stri_four']
if ex_li[0] != '':
campaignID = ex_li[0]
else:
campaignID = ''
if ex_li[1] != '':
keywordID = ex_li[1]
else:
keywordID = ''
.........
.......
try:
cursor = conn.cursor()
query = "insert into PerformaceReport(campaignID, keywordID, keyword, avgPosition,cost)"
query += "VALUES (%s, '%s', '%s', '%s')" %(campaignID, keywordID, keyword, avgPosition,cost)
cursor.execute( query )
conn.commit()
except Exception as e:
print e,"!!!! Exception happend!!!!"
在上面的代码中,如果它们不等于空字符串,我将从列表中获取字符串,因为在切片期间如果没有字符串,它将显示list index out of range
错误。
那么有没有办法在一行中编写这些if和else语句并将其作为值提交直接查询如下所示(仅作为一个想法)
query += "VALUES (%s, '%s', '%s', '%s')" %(if ex_li[0] != '': campaignID = ex_li[0] else: campaignID = '' ............)
答案 0 :(得分:8)
expression_if_true if condition else expression_if_false
所以试试
campaignID = main_res[0] if ex_li[0] != '' else ''
答案 1 :(得分:1)
您可以使用this SO answer中的三元表达式(v2.5)。但我会建议:
names = ['campaignID', 'keywordID' ... ]
data = itertools.izip_longest(names, ex_li)
key_string = ','.join(data.keys())
query = '...(' + key_string + ')...( %s, %s, %s, %s )' #no % here
cursor.execute(query, data.values())
在回答您修改后的问题时,您在其中测试ex_li[0]
然后分配其值,没有必要检查空白并在找到它时分配,您可以这样做:
campaignID = ex_li[0]
如果ex_li[0]
是''
,那就是campaignID
中的内容。你提到list index out of bounds
,但除非你的列表长度不合适,否则在更新的代码中不会发生这种情况。
但是在更高级别,您可以完全删除这些if语句:
(campaignID, keywordID, ...) = ex_li
这是元组拆包。或者构建一个字典,这似乎更有用,因为您需要将ID视为数据和选择器:
names = ['campaignID', 'keywordID' ... ]
data = zip(names, ex_li)
# now have data = {'campaignID': ex_li[0], ... }
您可以适当地构建您的查询:
query = 'insert into Performance report (' + ','.join(data.keys()) + ') ' +
'values (' + ','.join("'"+elem+"'" for elem in data.values()) + ')'
一个改进可能是,如果你得到None
而不是一个空字符串(它将成为'None'
作为字符串),那么修改为zip读取的值:
data = zip(names, (elem or '' for elem in ex_li))
那应该给你空字符串而不是'无'。
如果thg435是正确的,你有时会得到一个较短的列表,那么你可以输入一些额外的''
:
data = zip(names, itertools.chain((elem or '' for elem in ex_li),
itertools.repeat('')))
此处repeat
将提供无尽的''
列表,chain
将从ex_li中获取元素,直到它用完为止,然后从''
开始获取repeat
{1}}。 zip
运行直到一个或其他迭代器用完,因此当names
耗尽时它将停止。或者,如果您希望单独处理None
值,则可以izip_longest
:
data = itertools.izip_longest(names, ex_li)
key_string = ','.join(data.keys())
value_string = ','.join("'"+str+"'" for str in
(elem or '' for elem in data.values()))
query = '...(' + key_string + ')....(' + value_string + ')...'
或为了便于阅读:
def quotify(str):
return "'"+str+"'"
然而,请勿这样做。在DB API中使用cursor.execute而不是自己引用值,因为许多SO问题都证明了这一点(例如Python: get escaped SQL string):
query = '...(' + key_string + ')...( %s, %s, %s, %s )' #no % here
cursor.execute(query, data.values())
这允许DB API为您正确地进行转义,防止注入攻击或事故。
答案 2 :(得分:0)
您可以尝试以下内容:
value_when_true if condition else value_when_false
答案 3 :(得分:0)
你也可以这样做:
campaignID = ex_li[0] and main_res[0] or ''
(当您的决定基于您评估为真或假的第一个值时起作用)
答案 4 :(得分:0)
query += "VALUES (%s, '%s', '%s', '%s')" %(ex_li[0] if ex_li[0] != '' else '', ............)
您无法像这样指定表达式的一部分,但您可以这样做:
campaignID = ex_li[0] if ex_li[0] != '' else ''
query += "VALUES (%s, '%s', '%s', '%s')" %(campaignID, ............)
如果您想保留引用并稍后使用campaignID