2013-07-08 4 views
2

Я пытаюсь вставить проанализированные данные dta в базу данных postgresql, каждая строка которой является отдельной таблицей переменных, и она работала до тех пор, пока я не добавил во второй строке «recodeid_fk». Ошибка, которую я получаю при попытке запустить этот код: pg8000.errors.ProgrammingError: ('ERROR', '42601', 'синтаксическая ошибка в или рядом с "imp"').Ошибка синтаксиса при попытке вставить данные в postgresql

В конце концов, я хочу иметь возможность одновременно анализировать несколько файлов и вставлять данные в базу данных, но если кто-нибудь может помочь мне понять, что происходит сейчас, это будет фантастично. Я использую Python 2.7.5, statareader - из записей разработки pandas 0.12, и у меня очень мало опыта в Python.

dr = statareader.read_stata('file.dta') 
a = 2 
t = 1 
for t in range(1,10): 
    z = str(t) 
    for date, row in dr.iterrows(): 
     cur.execute("INSERT INTO tblv00{} (data, recodeid_fk) VALUES({}, {})".format(z, str(row[a]),29)) 
    a += 1 
    t += 1 
conn.commit() 
cur.close() 
conn.close() 
+0

** НИКОГДА не интерполируйте значения непосредственно в SQL, как это **, вы оставите себя критически уязвимым для [SQL injection] (bobby-tables.com). Кроме того, в будущем, пожалуйста, сообщите о своей версии PostgreSQL в вопросах. Благодаря! –

+1

Кроме того, всякий раз, когда вы видите, что вы что-то делаете с SQL в цикле, подумайте «как я могу превратить это в заданную операцию». В этом случае я бы предложил использовать команду 'COPY' через поддержку' COPY' Psycopg2 для массового ввода строк в один проход от генератора. –

ответ

2

Для конкретной ошибки ...

Ошибка синтаксиса, вероятно, происходит из строк {}, которые нуждаются в кавычки вокруг них. execute() может позаботиться об этом для вас автоматически. Заменить

execute("INSERT INTO tblv00{} (data, recodeid_fk) VALUES({}, {})".format(z, str(row[a]),29)) 

execute("INSERT INTO tblv00{} (data, recodeid_fk) VALUES(%s, %s)".format(z), (row[a],29)) 

Имя таблицы завершается так же, как и раньше, но эти значения будут заполняться execute, который вставляет кавычки, если они необходимы. Может быть, execute может также заполнить имя таблицы, и мы могли бы полностью удалить format, но это было бы необычным использованием, и я предполагаю, что execute может (ошибочно) поставить кавычки посреди имени.

Но есть более хороший подход ...

Панда включает a function for writing DataFrames to SQL tables. Postgresql пока не поддерживается, но в простых случаях вы можете притворяться, что вы подключены к базе данных sqlite или MySQL и не испытываете никаких проблем.

Что вы намерены делать с z здесь? Как бы то ни было, вы перебираете z от '1' до '9', прежде чем переходить к следующему циклу. Должны ли петли быть вложенными? То есть вы хотели вставить содержимое dr в девять разных таблиц, называемых tblv001 через tblv009?

Если вы имеете в виду этот цикл для размещения разных частей dr в разных таблицах, пожалуйста, проверьте отступ вашего кода и уточните его.

В любом случае вышеуказанная ссылка должна позаботиться о вставке SQL.

Ответ Edit

Похоже t, z и a делают лишние вещи. Как насчет:

import pandas as pd 
import string 

... 

# Loop through columns of dr, and count them as we go. 
for i, col in enumerate(dr): 
    table_name = 'tblv' + string.zfill(i, 3) # e.g., tblv001 or tblv010 
    df1 = DataFrame(dr[col]).reset_index() 
    df1.columns = ['data', 'recodeid_fk'] 
    pd.io.sql.write_frame(df1, table_name, conn) 

Я использовал reset_index, чтобы индекс в колонке. Новый (последовательный) индекс не будет сохранен на write_frame.

+0

только что отредактировал мой код, чтобы уточнить ваш вопрос. Я намерен зацикливать разные части dr в отдельные таблицы – bhg23442

Смежные вопросы