Python — pyodbc, добавление уникальных значений в базу данных

#python #python-3.x #pyodbc

#python #python-3.x #pyodbc

Вопрос:

Как следует из названия, я пытаюсь проанализировать данные и вставить их в базу данных postgresql.

Следующие 2 функции — это то, что я использую, чтобы попытаться выполнить эту задачу. Как вы можете видеть, первая функция принимает входные данные и преобразует их в список списков.

Цикл for перебирает каждый из списков и присваивает их объекту. Вы можете видеть, что «insertToDatabase()» вызывается из цикла for и передает объекты в виде строк.

Установлено соединение с базой данных, и я сначала запускаю запрос, чтобы вернуть все post_id из базы данных и сохранить в списке. затем я пытаюсь выполнить «если идентификатор отсутствует в результатах», перейдите к insert .

Однако это не работает, мои записи добавляются каждый раз при запуске программы, создавая несколько одинаковых записей. Я попробовал что-то подобное, пытаясь получить только последнюю опубликованную запись, упорядоченную по убыванию метки времени, и выполнить «if id ! = last_posted», но это тоже не сработало.

Должен быть лучший способ сделать это. Что я здесь делаю не так? Если ‘id’ элемента (например, ‘7229511362’) уже существует в БД, я хочу пропустить повторную вставку его в БД и перейти к циклу to, чтобы проверить все результаты.

Код:

 def initialParse(results):
    rList = [list(r.values()) for r in results]

    print(rList)

    for l in rList:
        r_id = str(l[0])
        r_name = str(l[2])
        r_url = str(l[3])
        r_datetime = str(l[4])
        r_updated = str(l[5])
        r_price = str(l[6])
        r_where = str(l[7])

        insertToDatabase(r_id, r_name, r_url, r_datetime, r_updated, r_price, r_where)

def insertToDatabase(id, name, url, date, updated, price, where):
    global last_insert

    cnxn = connectDb()
    cursor = cnxn.cursor()
    cursor.execute('select post_id from listings order by tstmp desc')
    results = cursor.fetchall()

    print(results)

    try:
        if id not in results:
            Logger.writeAndPrintLine('Adding '   id   ' to database...', 0)
            cursor.execute("insert into listings (post_id, timestamp, url, subject, price, location, tstmp) values (" id ", '" date "', '" url "', '" name "', '" price "', '" where "', (current_timestamp));")
            print('inserted')
            cursor.commit()
            time.sleep(1)
    except:
        pass

    cursor.close()
    disconnectDb(cnxn)
  

пример входных данных после преобразования в список списков:

 [['7230609794', None, '2004 Nissan Sentra sedan automatic runs excellent', 'https://monterey.craigslist.org/cto/d/salinas-2004-nissan-sentra-sedan/7230609794.html', '2020-11-13 17:35', '2020-11-13 17:35', '$1,850', 'Salinas', True, None, False], ['7230559009', None, '2006 mini cooper', 'https://monterey.craigslist.org/cto/d/king-city-2006-mini-cooper/7230559009.html', '2020-11-13 15:38', '2020-11-13 15:38', '$3,000', 'King city', True, None, False]]
  

Пример того, какой курсор.fetchall() возвращает:

 [('7229511362', ), ('7229470879', ), ('7229511362', ), ('7229697890', ), ('7229839309', ), ('7229957054', ), ('7230191646', ), ('7230491972', ), ('7230558061', ), ('7230559009', ), ('7230609794', ), ('7229470879', ), ('7229511362', ), ('7229697890', ), ('7229839309', ), ('7229957054', ), ('7230191646', ), ('7230491972', ), ('7230558061', ), ('7230559009', ), ('7230609794', ), ('7229470879', ), ('7229511362', ), ('7229697890', ), ('7229839309', ), ('7229957054', ), ('7230191646', ), ('7230491972', ), ('7230558061', ), ('7230559009', ), ('7230609794', ), ('7229470879', ), ('7229697890', ), ('7229839309', ), ('7229957054', ), ('7230191646', ), ('7230491972', ), ('7230558061', ), ('7230559009', ), ('7230609794', ), ('7229470879', ), ('7229697890', ), ('7229839309', ), ('7229957054', ), ('7230191646', ), ('7230491972', ), ('7230558061', ), ('7230559009', ), ('7230609794', )]
  

Ответ №1:

.fetchall() возвращает список pyodbc.Row объектов. Если вы хотите использовать in для проверки, было ли возвращено определенное значение идентификатора, сначала вам нужно преобразовать этот список Row объектов в список скалярных значений:

 crsr = cnxn.cursor()
rows = crsr.execute("""
SELECT 'foo' AS col1
UNION ALL
SELECT 'bar' AS col1
""").fetchall()
print(rows)  # [('foo', ), ('bar', )]
print("foo" in rows)  # False
ids = [row[0] for row in rows]
print(ids)  # ['foo', 'bar']
print("foo" in ids)  # True