@isaac-21

Как избавиться от ошибки при создании БД?

При запуске скрипта, первый раз выдается ошибка (если в бд нет такой таблицы), второй раз при запуске, уже все нормально работает (поскольку в первый раз, вместе с ошибкой создало и таблицу). Как избавиться от этого, чтобы с первого раза (если в бд нет таблицы) не выкидывало ошибку?

from sqlalchemy import create_engine, Column, BIGINT, String, Integer, FLOAT
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from .items import BrainboyItem
import pymysql

pymysql.install_as_MySQLdb()
Base = declarative_base()


class Data(Base):
    __tablename__ = 'BrainBoy'

    id = Column(BIGINT, primary_key=True, autoincrement=True)
    name = Column(String(1000, collation='utf8mb4_unicode_ci'), index=True)
    number_game = Column(Integer)
    points = Column(FLOAT)

    def __init__(self, name, number_game, points):
        self.name = name
        self.number_game = number_game
        self.points = points


class BrainboyPipeline(object):

    def __init__(self):
        basename = 'data_scraped'
        self.engine = create_engine("mysql://huston:fil@localhost/pars", encoding="utf8")
        Base.metadata.create_all(self.engine)
        self.session = Session(bind=self.engine)

    def process_item(self, item, spider):
        # Проверка нет ли уже такой команды
        if self.session.query(Data).filter(Data.name == item['name']).count():
            self.session.query(Data).filter(Data.name == item['name']). \
                update({Data.number_game: item['number_game'], Data.points: item['points']}, synchronize_session=False)

        else:
            result = Data(item['name'], item['number_game'], item['points'])
            self.session.add(result)

    def close_spider(self, spider):
        self.session.commit()
        self.session.close()

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/twisted/internet/defer.py", line 1418, in _inlineCallbacks
    result = g.send(result)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/crawler.py", line 87, in crawl
    self.engine = self._create_engine()
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/crawler.py", line 101, in _create_engine
    return ExecutionEngine(self, lambda _: self.stop())
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/core/engine.py", line 70, in __init__
    self.scraper = Scraper(crawler)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/core/scraper.py", line 71, in __init__
    self.itemproc = itemproc_cls.from_crawler(crawler)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/middleware.py", line 53, in from_crawler
    return cls.from_settings(crawler.settings, crawler)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/middleware.py", line 35, in from_settings
    mw = create_instance(mwcls, settings, crawler)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/scrapy/utils/misc.py", line 173, in create_instance
    instance = objcls(*args, **kwargs)
  File "/home/huston/PycharmProjects/parsing_kviz/brainboy/brainboy/pipelines.py", line 41, in __init__
    Base.metadata.create_all(self.engine)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/schema.py", line 4553, in create_all
    bind._run_visitor(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2095, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1656, in _run_visitor
    visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/visitors.py", line 145, in traverse_single
    return meth(obj, **kw)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/ddl.py", line 783, in visit_metadata
    self.traverse_single(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/visitors.py", line 145, in traverse_single
    return meth(obj, **kw)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/ddl.py", line 839, in visit_table
    self.traverse_single(index)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/visitors.py", line 145, in traverse_single
    return meth(obj, **kw)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/ddl.py", line 868, in visit_index
    self.connection.execute(CreateIndex(index))
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1011, in execute
    return meth(self, multiparams, params)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/sql/ddl.py", line 72, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1068, in _execute_ddl
    ret = self._execute_context(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1316, in _execute_context
    self._handle_dbapi_exception(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1510, in _handle_dbapi_exception
    util.raise_(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
    raise exception
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 1276, in _execute_context
    self.dialect.do_execute(
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 609, in do_execute
    cursor.execute(statement, parameters)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/cursors.py", line 148, in execute
    result = self._query(query)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/cursors.py", line 310, in _query
    conn.query(q)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/connections.py", line 548, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/connections.py", line 775, in _read_query_result
    result.read()
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/connections.py", line 1156, in read
    first_packet = self.connection._read_packet()
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/connections.py", line 725, in _read_packet
    packet.raise_for_error()
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "/home/huston/PycharmProjects/parsing_kviz/venv/lib/python3.8/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1071, 'Specified key was too long; max key length is 3072 bytes')
[SQL: CREATE INDEX `ix_BrainBoy_name` ON `BrainBoy` (name)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
  • Вопрос задан
  • 176 просмотров
Решения вопроса 1
name = Column(String(1000, collation='utf8mb4_unicode_ci'), index=True)
.....
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1071, 'Specified key was too long; max key length is 3072 bytes')

Видно же, что код пытается создать индекс большей длины, чем возможно. Сделайте поле короче или не индексируйте его. Для хранилища InnoDB можно создать индекс длиной максимум 768 байт (не символов, т.к. в многобайтовых кодировках символ может занимать до 3-х байт). Цитата:
The index key prefix length limit is 767 bytes for InnoDB tables that use the REDUNDANT or COMPACT row format. For example, you might hit this limit with a column prefix index of more than 255 characters on a TEXT or VARCHAR column, assuming a utf8mb3 character set and the maximum of 3 bytes for each character.

https://dev.mysql.com/doc/refman/5.7/en/innodb-lim...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
alfss
@alfss
https://career.habr.com/alfss
Не использовать MySQL. Ограничение на длину колонки в индексе.
Вот почему второй раз отрабатывает, это уже загадка.
Ответ написан
Комментировать
@Triplicate
Здравствуйте, судя по ошибке - ограничение на длину колонки в индексе.
Вам предлагают [SQL: CREATE INDEX `ix_BrainBoy_name` ON `BrainBoy` (name)]

То есть создайте индекс: ссылка на доку

Примерно: CREATE INDEX `ix_BrainBoy_name` ON `BrainBoy` ( name(32) )
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы