Ошибка pymysql.err.IntegrityError

111
04 сентября 2021, 09:00

Пытаюсь сделать insert новостей в бд.И чтобы повторные новости не добавлялись.Есть такой метод проверку url новости:

# < Проверка новости на наличие в БД.
    def check_exist_link(self, resource_link):
        self.cursor.execute('SELECT `link` FROM items WHERE `link` = "'+resource_link+'"')
        exists_links = self.cursor.fetchall()
        # < Проверка на наличие новости в БД.
        if len(exists_links) == 0:
            # < Если вернет false значит новости в бд нету.
            return False
        else:
            # < Если вернет true значит новость в бд есть.
            return True

Но что-то этот метод работает не корректно. Перед insert у меня стоит такое условие:

if exist_link is not True:
    huge_insert = parser.huge_insert_db(query)

Вот собственно сам traceback:

Traceback (most recent call last):
  File "C:PycharmProjects/oop_parser/main_parser.py", line 59, in <module>
    huge_insert = parser.huge_insert_db(query)
  File "C:PycharmProjects\oop_parser\boilerpipe_parser_component.py", line 132, in huge_insert_db
    self.cursor.execute(query)
  File "C:AppData\Local\Programs\Python\Python37-32\lib\site-packages\pymysql\cursors.py", line 170, in execute
    result = self._query(query)
  File "C:AppData\Local\Programs\Python\Python37-32\lib\site-packages\pymysql\cursors.py", line 328, in _query
    conn.query(q)
  File "C:AppData\Local\Programs\Python\Python37-32\lib\site-packages\pymysql\connections.py", line 517, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "C:Local\Programs\Python\Python37-32\lib\site-packages\pymysql\connections.py", line 732, in _read_query_result
    result.read()
  File "C:Local\Programs\Python\Python37-32\lib\site-packages\pymysql\connections.py", line 1075, in read
    first_packet = self.connection._read_packet()
  File "C:Local\Programs\Python\Python37-32\lib\site-packages\pymysql\connections.py", line 684, in _read_packet
    packet.check_error()
  File "C:Local\Programs\Python\Python37-32\lib\site-packages\pymysql\protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "C:Programs\Python\Python37-32\lib\site-packages\pymysql\err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.IntegrityError: (1062, "Duplicate entry 'http://bryansk-news.net/incident/2019/10/08/37541.html' for key 'link'")
Process finished with exit code 1

Что я делаю не так ? С чего стоит начать копать ?

UPD: Эврика ! Я понял в чем ошибка.На этом ресурсе который парсится.Есть новости которые повторяются.Решение это в методе:get_resource_links сделать проверку на повторяющиеся ссылки.

def get_resource_links(self, resource_page , link_rule, resource_domain):
        resource_links = []
        soup = BeautifulSoup(resource_page, 'lxml')
        resource_links_blocks = soup.findAll(link_rule[0], {link_rule[1]: link_rule[2]})
        for resource_link_block in resource_links_blocks:
            a_tag = resource_link_block.find('a')
            if a_tag:
                link = a_tag.get('href')
                if resource_domain not in link:
                    resource_links.append(resource_domain + link)
                else:
                    resource_links.append(link)
        return resource_links

Теперь встал вопрос,как это можно реализовать ?

Answer 1

Вместо INSERT INTO ... используйте INSERT IGNORE INTO ... тогда дубликаты не будут добавляться и не будет той ошибки.

Например, был запрос:

INSERT INTO users_partners (uid,pid) VALUES (1,1);

А станет:

INSERT IGNORE INTO users_partners (uid,pid) VALUES (1,1);
Answer 2

Эврика ! Я понял в чем ошибка.На этом ресурсе который парсится.Есть новости которые повторяются.Решение это в методе:get_resource_links сделать проверку на повторяющиеся ссылки.

def get_resource_links(self, resource_page , link_rule, resource_domain):
        resource_links = []
        soup = BeautifulSoup(resource_page, 'lxml')
        resource_links_blocks = soup.findAll(link_rule[0], {link_rule[1]: link_rule[2]})
        for resource_link_block in resource_links_blocks:
            a_tag = resource_link_block.find('a')
            if a_tag:
                link = a_tag.get('href')
                if resource_domain not in link:
                    resource_links.append(resource_domain + link)
                else:
                    resource_links.append(link)
        # < Отсеивание ссылок на уникальные.
        resources_links = unique(resource_links)
        return resources_links

В итоге все работает.

Огромная благодарность пользователю gil9red

READ ALSO
Как вывести теги?

Как вывести теги?

есть запрос для ввода статей

244
mysql left join не верно срабатывает

mysql left join не верно срабатывает

при таком запросе,

190
Как лучше хранить контент в БД: HTML vs MarkDown?

Как лучше хранить контент в БД: HTML vs MarkDown?

Есть очень большая база данных с статьямиОни сейчас в формате html

260
Django и MySQL с помощью docker-compose

Django и MySQL с помощью docker-compose

Дело происходит ubuntaБез докера пара Django и MySQL, а вот мой докер здесь лишний и портит жизнь всем, включая меня

174