Построить динамический c INSERT запрос с psycopg2 - PullRequest
0 голосов
/ 12 февраля 2020

В настоящее время я пишу небольшой инструмент для перемещения данных из SQL Sever DB в postgres DB. Соединение с базой c на данный момент все нормально работает.

Мне очень трудно создавать запросы динамически. Это должно быть динамически c, так как там много таблиц и много столбцов, которые нужно переместить. Также порядок и имена таблиц и столбцов не обязательно совпадают с get go. Я уже сопоставил старые и новые столбцы с данными, последнее, что мне нужно сделать, это создать операторы вставки. Делать это по столбцам тоже нельзя, так как не пустые ограничения не позволяют вставлять только одно значение за раз.

Python 3.7.2

Postgres 12

Windows 10 64 бит

По сути, то, что я хочу, в псевдокоде выглядит примерно так:

INSERT INTO {tableName} {columnList} VALUES {valueList}

После попытки нескольких вариантов того, что по сути было манипулированием строками, и ссылки на эти ресурсы / SO сообщения:

http://aklaver.org/wordpress/2018/04/21/building-dynamic-sql-using-psycopg2/

https://www.psycopg.org/docs/usage.html#query -параметры

https://www.psycopg.org/docs/sql.html#module -psycopg2. sql

build SQL динамический c запрос с библиотекой psycopg2 python и с использованием хороших инструментов преобразования типа

Я пришел пока что с этим кодом:

# wfData -- List of Lists which contain data, of mixed data types(int,str,NULL), every list is a row from #the database
# tableName -- Name of the table i want to insert into, as a string
# columnMap -- List of lists, which contain the matched column names --> [[col1_old,col2_old,..],[col1_new,col2_new,...]]
def addData(self, wfData, tableName, columnMap ):
    cursor = self.cursor
    for row in wfData:
        insert_str = sql.SQL("INSERT INTO {tableName} ({}) VALUES ({})").format(
        sql.SQL(",").join(map(sql.Identifier, columnMap[1])),
        sql.SQL(",").join(map(sql.Placeholder, row)),
        sql.Identifier(tableName)
        )
        try:
            cursor.execute(insert_str)
        except Exception as e:
            print(e)
        return

Попытка запустить этот код приводит к следующей ошибке: expected string or None as name, got 1, которая оставляет меня потерянным, потому что я действительно не знаю, происходит ли это из-за некоторых проблем преобразования типов, которые я Подозреваю, что если то, что я пытаюсь здесь приготовить, просто неправильно.

Спасибо за ваш совет.

* 104 2 * EDIT 1

Я изменил порядок своих параметров, но безрезультатно. Ошибка все та же. Но я сделал интересное открытие: вернувшись к источникам, упомянутым выше, мне удалось заставить все это, по крайней мере, прокручивать строку SQL, которая все еще не работает, но progres является proges. Судя по изменениям, которые я сделал, кажется, что моя структура данных вызывала ошибку до тех пор, пока данные не организованы в списки. Теперь я изменил его в словарь с именем test:

# wfData -- List of Lists which contain data, of mixed data types(int,str,NULL), every list is a row from #the database
# tableName -- Name of the table i want to insert into, as a string
# columnMap -- List of lists, which contain the matched column names --> [[col1_old,col2_old,..],[col1_new,col2_new,...]]
    def addData(self, wfData, tableName, columnMap ):
        cursor = self.cursor
        test = {"id": 1}
        for row in wfData:
            try:
                insert_str = sql.SQL("INSERT INTO {} ({}) VALUES ({})").format(
                sql.Identifier(tableName),
                sql.SQL(",").join(map(sql.Identifier, test)),
                sql.SQL(",").join(map(sql.Placeholder, test))
                )
                cursor.execute(insert_str)

            except Exception as e:
                print(e)
            exit()
        return

Теперь я получаю эту ошибку:

ERROR:  Syntaxerror at »%«
LINE 1: INSERT INTO "gr_akt_a" ("id") VALUES (%(id)s)
#The printed sql string :
Composed([SQL('INSERT INTO '), Identifier('graves_cur_h'), SQL(' ('), Composed([Identifier('id')]), SQL(') VALUES ('), Composed([Placeholder('id')]), SQL(')')])

1 Ответ

0 голосов
/ 13 февраля 2020

Я сделал это. Проблема была в моей структуре данных. Я пытался обработать все со списками и перепутал некоторую обработку списков с некоторыми из обработки словаря, короче, это был беспорядок, но теперь мне удалось заставить все работать:

def addData(self, wfData, tableName, columnMap ):
    cursor = self.cursor      
    for row in wfData:
        test = dict(zip(columnMap[1],row)) #this is where the magic starts
        try:
            insert_str = sql.SQL("INSERT INTO {} ({}) VALUES ({})").format(
            sql.Identifier(tableName),
            sql.SQL(",").join(map(sql.Identifier, test)),
            sql.SQL(",").join(map(sql.Placeholder, test))
            )
            print(type(insert_str))
            cursor.execute(insert_str, test)# the 'test' here is crucial i just forgot it
        except Exception as e:
            print(e)
        exit()
    return

Теперь выполняется запрос вставки, он все еще падает, но это проблема, связанная с данными. На данный момент я пытаюсь переместить сервер geometry vom sql на postgis без какой-либо обработки. Любые советы для такого рода вещей приветствуются.

...