2009-12-18 76 views
1

我不习惯Python的方式,但我几乎可以确定下面的脚本可以被压缩。我不在这里寻找速度优化,我正在寻找更可读的代码。让所有我关心的都慢一些,但是有什么方法可以让这看起来更像Python。这个python脚本可以缩短/优化,怎么样?

我只是读了一个csv文件,里面装满了邮编,并填充了23列的数据库。很多打字。我也不喜欢硬编码的东西,如行的索引。另外,multis ='%s,'* 23,然后是multis = multis [: - 2]感觉很脏。

期待看到你们能想出什么。

#!/usr/bin/python 

import csv 
import MySQLdb 

db = MySQLdb.connect(host="localhost", user="root", db="test") 
c = db.cursor() 
f_csv = 'zip-codes-database-STANDARD.csv' 
csvReader = csv.reader(open(f_csv)) 
ziplist = [] 
multis = '%s, '*23 
multis = multis[:-2] 
for row in csvReader: 
    c.execute("""INSERT INTO lock_zipcodes_complete 
      (`zipcode`, `city`, `state`, `county`, `areacode`, 
      `citytype`, `city_alias_abbreviation`, 
      `city_alias_name`, `latitude`, `longitude`, `timezone`, 
      `elevation`, `county_fips`, `dst`, 
      `preferred_last_line_key`, `classification_code`, 
      `multicounty`, `state_fips`, `city_state_key`, 
      `city_alias_code`, `primary_record`, `city_mixed_case`, 
      `city_alias_mixed_case`) VALUES(""" + multis + ')', 
      (row[0], row[1], row[2], row[3], row[4], row[5], row[6], 
      row[7], row[8], row[9], row[10], row[11], row[12], 
      row[13], row[14], row[15], row[16], row[17], row[18], 
      row[19], row[20], row[21], row[22])) 
+0

你想让它短于10行代码!? – 2009-12-18 02:59:28

+0

不会更短,我只是想方设法让它不那么冗长。我知道我使用上面的元组行的方式是不正确的。也是多重字符串。只是想让一些Python大师展示他们如何改变它的例子,以便我可以学习。 – randombits 2009-12-18 03:14:41

+0

迄今为止的答案都没有解释为什么这是如此,但请注意您的查询存在“SQL注入攻击”的危险,并且通常被认为是使用数据库的一种非常危险的方式。 (在这种情况下,如果你控制输入数据是安全的,但却是一个不好的习惯。) – 2009-12-18 14:05:04

回答

7

这一部分:

multis = '%s, '*23 
multis = multis[:-2] 

应该

multis = ', '.join(['%s'] * 23) 

ziplist没有使用,所以你可以删除,设置它的线。

  (row[0], row[1], row[2], row[3], row[4], row[5], row[6], 
      row[7], row[8], row[9], row[10], row[11], row[12], 
      row[13], row[14], row[15], row[16], row[17], row[18], 
      row[19], row[20], row[21], row[22]) 

应该只是tuple(row)(对于特定的方式你使用它,只是row都行)。

INSERT中显式列名称列表令人不快,但如果您不确定是否该数据库表中的所有列或订单是否正确(或者,当然,如果您确定要么情况并非如此);但这是一个SQL - vs - CSV“阻碍不匹配”问题,而不是Python的一个问题;-)。

整个循环:

for row in csvReader: 
    c.execute(sql_statement, row) 

可以任选进一步被压缩到:

c.executemany(sql_statement, csvReader) 
+0

明确列出列名总是一个好主意 - 即使输入数据符合,也不要使用它。如果你在插入语句中列出列名(如果你只是存储它,那么你不会花费太多的代价),那么稍后重构你的数据库会变得更容易。 – 2009-12-18 03:07:05

3

请不要构建这样的SQL文本。请不要。请。

首先。变量ziplist未使用。删除它。

二。使用真正的SQL绑定。

c.execute("INSERT...", row) 

这被记录在MySQLdb接口中。 http://mysql-python.sourceforge.net/MySQLdb-1.2.2/