2009-12-18 10 views
1

Je n'ai pas encore l'habitude de faire les choses en python, mais je suis presque certain que le script suivant peut être condensé. Je ne cherche pas l'optimisation de la vitesse ici, je cherche un code plus lisible. Rends-le plus lent pour tout ce qui m'importe, mais quelles sont les façons de rendre ce look plus Python-esque. Je lis simplement dans un fichier csv rempli de codes postaux et remplit une base de données de 23 colonnes. Beaucoup de frappe. Je n'aime pas non plus les choses codant dur comme l'index de la rangée. En outre, multis = '% s,' * 23 suivi de multis = multis [: - 2] semble sale.ce script python peut être raccourci/optimisé, comment?

Dans l'attente de voir ce que certains d'entre vous peuvent trouver.

#!/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

vous le souhaitez moins de 10 lignes de code !? –

+0

Pas plus court, je cherchais juste des moyens de le rendre moins bavard. Je savais que la façon dont j'utilise la ligne de tuple ci-dessus est incorrecte. Aussi la chaîne multis. Je voulais juste des gourous python pour montrer un exemple de la façon dont ils changeraient pour que je puisse apprendre. – randombits

+0

Aucune réponse à ce jour n'a expliqué pourquoi il en est ainsi, mais notez que votre requête court le risque d'une "attaque par injection SQL" et est généralement considérée comme un moyen très dangereux d'utiliser des bases de données. (Sûr dans ce cas si vous contrôlez les données d'entrée, mais une mauvaise habitude d'entrer.) –

Répondre

7

Cette partie:

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

devrait être

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

ziplist n'est pas utilisé, de sorte que vous pouvez simplement supprimer la ligne qui la caractérise.

  (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]) 

devrait être juste tuple(row) (pour la manière spécifique que vous utilisez, juste row fera). La liste explicite des noms de colonne dans le INSERT est désagréable, mais nécessaire si vous n'êtes pas sûr que ce soit toutes les colonnes de cette table DB ou si la commande est correcte (ou, bien sûr, si vous êtes sûr que soit n'est pas le cas); mais c'est un problème de "discordance d'impédance" SQL-vs-CSV plutôt qu'un problème de Python ;-).

la boucle entière:

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

peut, éventuellement, en outre être compacté à:

c.executemany(sql_statement, csvReader) 
+0

La liste explicite des noms de colonne est toujours une bonne idée - résistez à l'envie de ne pas l'utiliser, même si vos données d'entrée sont conformes. Si vous répertoriez les noms de colonne dans vos instructions d'insertion (quelque chose qui ne vous coûtera pas trop de frappe si vous le stockez simplement), le refactoring de votre base de données deviendra plus facile. –

3

Ne créez pas de texte SQL comme ça. Merci de ne pas. S'il vous plaît.

Premier. La variable ziplist n'est pas utilisée. Supprime-le.

Deuxième. Utilisez la liaison SQL réelle.

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

Ceci est documenté dans l'interface MySQLdb. http://mysql-python.sourceforge.net/MySQLdb-1.2.2/.

Questions connexes