Почему кажется, что sqlalchemy спонтанно выполняет одни запросы, игнорируя другие? - PullRequest
2 голосов
/ 28 мая 2020

У меня есть причудливая облачная функция GCP, которая на каком-то высоком уровне выполняет неразумный парсинг веб-сайтов, используя преимущества веб-сайта, принимающего числовой восходящий параметр 'id'.

main. py

def upsert(db, i, x, y):
    with db.connect() as cursor:
        cursor.execute(f"REPLACE INTO TABLE_NAME (i, x, y) VALUES (i, \"{x}\", \"{y}\"")

def main(data, context):
    db = sqlalchemy.connect(...)

    for i in range(0, 100):
        soup = BeautifulSoup(f"websiteimscraping.com/id={i}")
        if soup is not valid:
            continue

        x = soup.find_all(...)
        y = soup.find_all(...)

        upsert(db, i, x, y)

В этом примере я точно знаю, что большинство, если не все идентификаторы от 0 до 99, действительны + уникальны, и у меня должно быть очень похожее количество строк в базе данных когда облачная функция завершена.

Чтобы убедиться, что у меня есть 100 строк в MySQL, я вхожу в режим отладки и оцениваю выражение:

list(cursor.execute("SELECT * FROM TABLE_NAME"))

и возвращаю 20% строк, которые я ожидал, без какого-либо подобия порядка. с идентификаторами вроде (7, 8, 9, 10, 13, 44, 45, 46, 47, 48, 49, 50, 51, 86)

Я делаю несколько операторов печати, чтобы убедиться, что ни один из моих краев запускаются случаи (что привело бы к пропуску недопустимого идентификатора), и действительно, в коде их нет, что я проверил, перейдя в режим отладки и просмотрев все идентификаторы, отправленные на шаг upsert.

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

Основное предположение, которое я делаю заключается в том, что если возникнет проблема с данными для строк, которые не вставляются, что вызвало бы некоторые проблемы с оператором REPLACE, sqlalchemy вызвал бы для меня исключение. sqlalchemy не вызывал исключений во всей функции.

Есть ли какие-нибудь не данные, связанные с sqlalchemy, из-за которых строки не вставляются?

Я попытался найти шаблоны в данных для строк, которые были вставлены, чтобы попытаться измерить некоторую (не) согласованность или закономерности данных (которые могут показаться более вероятными), но не нашел их.

Я sh мне было проще отдать код для воспроизведения, но я почти уверен, что никто не захочет создавать свой собственный mysql экземпляр, чтобы попробовать это - если да, то я Я счастлив предоставить реальный код, и вы можете попробовать его сами.

1 Ответ

1 голос
/ 29 мая 2020

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

Проблема в том, что вы используете оператор REPLACE. Как указано в документации MySQL оператор REPLACE работает точно так же, как операция INSERT , но , если PRIMARY KEY уже существует, указанная строка заменена вместо сбой запроса.

Согласно вашему общему коду, похоже, что вы используете поле code как PRIMARY KEY, но вы проверяете поле id как индикатор вставленной веб-страницы. Что происходит, так это то, что несколько строк имеют одинаковые code, поэтому каждый раз, когда одна вставляется, предыдущая удаляется.

Я решил вашу проблему, просто сделав поле id PRIMARY KEY вместо code. Как только вы измените это (не забудьте отбросить исходную таблицу), вы можете снова запустить свой код, и вы не увидите отсутствующих id s. Вы можете проверить это, используя:

SELECT id FROM CLASSES_MASTER;

Кстати, теперь, когда у вас есть все данные, вы можете проверить количество повторяющихся кодов с помощью этого:

SELECT code, COUNT(*) FROM CLASSES_MASTER GROUP BY code;
...