2012-08-04 17 views
10

Imagine que tiene un diccionario (o una lista) de Python con valor clave con cantidades mayores de elementos. Digamos que está leyendo un archivo JSON más grande y le gustaría almacenar sus contenidos en la tabla MySQL con claves como nombres de columnas y valores como valores.¿Cuál es la forma más efectiva de insertar diccionarios/listas de Python en la base de datos SQL?

JSON Ejemplo:

"display_location": { 
    "city":"Bratislava", 
    "state_name":"Slovakia", 
    "country_iso3166":"SK", 
    "latitude":"48.20000076", 
    "longitude":"17.20000076", 
} 

entonces es muy ineficaz para escribir SQL de inserción como esto manualmente:

INSERT INTO TABLE (city, state_name, country_iso3166, latitude, longitude) VALUES('%s','%s','%s','%s','%s') 
% (Bratislava, Slovakia, SK, 48.20000076, 17.20000076); 

(Bueno, está bien, con cinco valores, pero imagina que hay, por ejemplo, de cinco cientos de ellos.)

¿Existe alguna clase/método de Python para insertar SQL eficaz y de cadena corta? Escribí este trozo de código:

for key,value in list.iteritems(): 
    value_type = type(value) 
    if value_type is unicode: 
     vars_to_sql.append(value.encode('ascii', 'ignore')) 
     keys_to_sql.append(key.encode('ascii', 'ignore')) 
    else: 
     vars_to_sql.append(value) 
     keys_to_sql.append(key) 

keys_to_sql = ', '.join(keys_to_sql) 

Después de que el inserto se ve mucho más simple:

INSERT INTO conditions_bratislava(%s) VALUES %r" % (keys_to_sql, tuple(vars_to_sql),) 

No puede haber miles de valores y todavía va a estar bien con esta declaración de un inserto.

Tenga en cuenta que la condición que decodifica cadenas Unicode, por lo que no tendrá letras "u" antes de cada valor.

Entonces, ¿hay alguna clase o método más efectivo y preparado para insertar muchos valores en el mismo enfoque simple con una cadena INSERT corta?

+1

Si desea utilizar una base de datos relacional, tal vez utilice la próxima versión de PostgreSQL 9.2 que tiene un tipo de datos JSON nativo. –

Respuesta

6

Si los datos se estructura como esa, que se prestaría más hacia una base de datos orientada documento (Mongo/Couch etc ...)

Puede salirse con algo como esto ... Creo que el uso de repr está siendo un poco demasiado inteligente ...

insert_sql = 'INSERT INTO conditions_bratislava(%s) values(%s)' 
cols = ', '.join(somedict) 
vals = ', '.join('?' * len(somedict)) # or whatever qparam is required 
to_execute = insert_sql % (cols, vals) 
some_cursor.execute(to_execute, somedict.values()) 

En una nota:

value_type = type(value) 
if value_type is unicode: 

debe ser escrita como:

if isinstance(value, unicode): 
+0

+1 en 'isinstance' –

+0

Si el dict se modifica en un segundo subproceso, esto puede producir un orden incorrecto de los valores o demasiados valores. Me gustaría ir con parámetros nombrados en su lugar y pasar todo el diccionario a cursor.execute. – XORcist

+0

@ möter Estaba ofreciendo la versión "más correcta" de lo que estaba haciendo el PO. Sin embargo, estoy de acuerdo en que el uso de parámetros con nombre es algo mejor en general. También espero que cualquiera que use hilos sea lo suficientemente cauteloso como para usar el bloqueo. –

Cuestiones relacionadas