Неожиданный EOF при разборе таблицы - PullRequest
0 голосов
/ 23 февраля 2019

Я пытаюсь сделать скрипт на python, который будет извлекать данные из первой таблицы и вводить их в другую таблицу.Вроде как ETL некоторых сортов.Однако я сталкиваюсь с этой SyntaxError: unexpected EOF while parsing ошибкой.Я стараюсь изо всех сил и пытаюсь использовать методы, которые, как я видел, используют другие, поэтому я не очень разбираюсь в этом.

Вот мой код:

import psycopg2
try:
    connectionone = psycopg2.connect(user = "postgres",
                      password = "xxxxxx",
                      host = "127.0.0.1",
                      port = "5432",
                      database = "xxxxxx")
    connectiontwo = psycopg2.connect(user = "postgres",
                      password = "xxxxxx",
                      host = "127.0.0.1",
                      port = "5432",
                      database = "xxxxxx")

    cursorsource = connectionone.cursor()
    cursordest = connectiontwo.cursor()
    #Truncating dest table
    print("Truncating Destination")
    cursordest.execute('delete from testarea.salepersons_2')
    connectiontwo.commit()

    #Fetch source data
    cursorsource.execute('SELECT sp_no, sp_name, sp_territory, sp_product, 
     active FROM testarea.salepersons_original;') 
    rows = cursorsource.fetchall()

    sql_insert = 'INSERT INTO testarea.salepersons_2 (sp_no, sp_name,  
      p_territory, sp_product, active) values '
    sql_values = ['(%s, %s, %s, %s, %s)'] 

    data_values = []

    batch_size = 1000 #customize for size of tables... 

    sql_stmt = sql_insert + ','.join(sql_values*batch_size) + ';'

    for i, row in enumerate(rows, 1):

                data_values += row[:5] #relates to number of columns (%s)
                if i % batch_size == 0:
                    cursordest.execute (sql_stmt , data_values )
                    cursordest.commit()
                    print("Inserting")
                    data_values = []

    if (i % batch_size != 0):
        sql_stmt = sql_insert + ','.join(sql_values*(i % batch_size)) + 
        ';'
        cursordest.execute (sql_stmt, data_values)
        print("Last Values ....")
        connectiontwo.commit()
except (Exception, psycopg2.Error) as error :
        print ("Error occured :-(", error)
finally:
    #closing database connection.
        if(connectionone):
            cursorsource.close()
            connectionone.close()
            print("PostgreSQL connection is closed")

    #closing database connection.
        if(connectiontwo):
            cursordest.close()
            connectiontwo.close()
            print("PostgreSQL connection is closed")
#close connections
cursorsource.close()
cursordest.close()
cursorsource.close()
cursordest.close()

1 Ответ

0 голосов
/ 23 февраля 2019

Первый вопрос достаточно прост для решения.У вас есть многострочная строка, заключенная только в одинарные кавычки:

cursorsource.execute('SELECT sp_no, sp_name, sp_territory, sp_product, 
    active FROM testarea.salepersons_original;') 

Вы должны заключить ее в тройные кавычки, что не повлияет на выполнение SQL:

cursorsource.execute("""SELECT sp_no, sp_name, sp_territory, sp_product, 
                        active FROM testarea.salepersons_original;""") 

Оставшийся кодМне трудно следовать.Я сомневаюсь, что на самом деле у вас есть таблица с 5000 столбцами, поэтому я думаю, что вы пытаетесь сделать 1000 вставок строк, содержащих 5 значений.Я могу дать общий подход к этому, только если мое понимание верно:

import random
import string

# Create some fake data to visualise
fake_data = [random.choice(list(string.ascii_letters)) for x in range(50)]

# Chunk the data (https://stackoverflow.com/a/1751478/4799172)
# This reshapes it into sublists each of length 5.
# This can fail if your original list is not a multiple of 5, but I think your
# existing code will still throw the same issues.
def chunks(l, n):
    n = max(1, n)
    return (l[i:i+n] for i in range(0, len(l), n))


chunked_data = chunks(fake_data, 5)

sql_insert = """INSERT INTO testarea.salepersons_2 (sp_no, sp_name, 
                sp_territory, sp_product, active) values (?, ?, ?, ?, ?)"""

# Use executemany, not execute in a loop, to repeat for each sublist in 
# chunked_data
cursor.executemany(sql_insert, chunked_data)

Обратите внимание, что в этом случае я использую параметризованный запрос для защиты от внедрения SQL (я использую ? как заполнители для значений).Разные библиотеки имеют разные заполнители;например, оболочки MySQL ожидают %s, в то время как SQLite ожидает ? - в этом случае я использовал ?, чтобы устранить неоднозначность, что это не просто обычное форматирование строки, но вам, возможно, придется вернуться обратно к %s.

...