Specified key was too long; max key length is 767 bytes'

6 years 6 months ago #1962 by veadm
veadm created the topic: Specified key was too long; max key length is 767 bytes'
Вот что получается при попытке инициализации. Попытка использования mariadb, в конфиге все подставлено по инструкции для работы с mysql и innodb. На сервере fedora 26, все компоненты предустановлены и python3 и mysqlclient и всё что в requrements.txt. В чем дело как исправить?

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'sopds',
        'HOST': 'localhost',
        'USER': 'sopds',
        'PASSWORD' : 'sopds',
      'OPTIONS' : {
      'init_command': """SET default_storage_engine=INNODB; \
                       SET sql_mode='STRICT_TRANS_TABLES'; \
                       SET NAMES UTF8 COLLATE utf8_general_ci; \
                       SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
                    """

      }
    }
}


# python3 manage.py migrate
System check identified some issues:

WARNINGS:
?: (urls.W005) URL namespace 'web' isn't unique. You may not be able to reverse all URLs in this namespace
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, database, opds_catalog, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying database.0001_initial... OK
  Applying opds_catalog.0001_initial...Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
    raise errorvalue
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
    res = self._query(query)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 411, in _query
    rowcount = self._do_query(q)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 374, in _do_query
    db.query(q)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/connections.py", line 277, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')

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

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/usr/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/usr/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/usr/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/usr/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/usr/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 93, in __exit__
    self.execute(sql)
  File "/usr/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 120, in execute
    cursor.execute(sql, params)
  File "/usr/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/usr/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 101, in execute
    return self.cursor.execute(query, args)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
    raise errorvalue
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
    res = self._query(query)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 411, in _query
    rowcount = self._do_query(q)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/cursors.py", line 374, in _do_query
    db.query(q)
  File "/usr/lib64/python3.6/site-packages/MySQLdb/connections.py", line 277, in query
    _mysql.connection.query(self, query)
django.db.utils.OperationalError: (1071, 'Specified key was too long; max key length is 767 bytes')

Please Войти or Create an account to join the conversation.

  • veadm
  • veadm's Avatar Topic Author
  • Offline
  • Новый участник
  • Новый участник
More
6 years 6 months ago #1963 by veadm
veadm replied the topic: Specified key was too long; max key length is 767 bytes'
Ну и в результате мы получаем:
# python3 manage.py sopds_util clear
System check identified some issues:

WARNINGS:
?: (urls.W005) URL namespace 'web' isn't unique. You may not be able to reverse all URLs in this namespace
Clear book database.
Installed 228 object(s) from 1 fixture(s)
[root@books sopds]# python3 manage.py createsuperuser
System check identified some issues:

WARNINGS:
?: (urls.W005) URL namespace 'web' isn't unique. You may not be able to reverse all URLs in this namespace

You have 6 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): opds_catalog, sessions.
Run 'python manage.py migrate' to apply them

Please Войти or Create an account to join the conversation.

  • veadm
  • veadm's Avatar Topic Author
  • Offline
  • Новый участник
  • Новый участник
More
6 years 6 months ago - 6 years 6 months ago #1964 by mitshel
mitshel replied the topic: Specified key was too long; max key length is 767 bytes'
Внимательно читаем п 2.4. инструкции (обращаем внимание на требования к версиям):


2.4 Использование InnoDB вместо MyISAM.
Указанная выше конфигурация MySQL использует в качестве движка БД MyISAM, который работает на большинтсве версий MySQL или MariaDB. Однако, если вы используете относительно свежие версии БД Mysql (MariaDB>=10.2.2, Mysql>=5.7.9), то у вас есть возможность использовать более современный движок InnoDB. Он несколько быстрее и поддерживает транзакции, что положительно скажется на целостности БД.
(На более старых версиях MySQL с ним возникают проблемы из-за ограничений на максимальную длину индексов.)
Таким образом, если у Вас современная версия MySQL (MariaDB>=10.2.2, Mysql>=5.7.9), то в настройках БД Mysql вместо указанных выше параметров OPTIONS просто используйте следующие....

Last Edit: 6 years 6 months ago by mitshel.

Please Войти or Create an account to join the conversation.

  • mitshel
  • mitshel's Avatar
  • Offline
  • Администратор
  • Администратор
More
6 years 3 months ago #2010 by dvs
dvs replied the topic: Specified key was too long; max key length is 767 bytes'
Извиняюсь что вмешиваюсь, но похоже это сюда.

Таблица opds_catalog_book.
Поле title и его клон поле search_title в котором находится то же самое только заглавными буквами.
Этот костыль приводит к распуханию индексов
mysql
where like "%тескт%" и так регистро независимый и прекрасно ищет по title.
+ есть функции lower() и upper()
а это минус 225 байт в индексации
Warning: Spoiler! [ Click to expand ]

Вижу что все where=["upper(title) like в коде закомментированы. Возможно поле просто не успели удалить.

Индексы filename и path
Warning: Spoiler! [ Click to expand ]

минус 512 байт.
Не смог придумать полезного функционала когда они необходимы.
Скорее всего используются для вебинтерфейса где список каталогов. Да прикольная вещь, только для конечного пользователя это 1 раз посмотреть и забыть. (сугубо субъективное мнение, может кому-то там интересно покопаться.)

На свой страх и риск у меня работает на mysql 5.6.36 c innodb. не жалуюсь.

Please Войти or Create an account to join the conversation.

  • dvs
  • dvs's Avatar
  • Offline
  • Новый участник
  • Новый участник
More
6 years 3 months ago - 6 years 3 months ago #2011 by mitshel
mitshel replied the topic: Specified key was too long; max key length is 767 bytes'
Не все так просто:
1. 737 байт - это ограничение на ОДИН индекс
2. Т.к. БД содержит не только ASCII символы, но и русские буквы, то используется кодировка UTF-8, а 1 символ UTF-8 это целых 4 байта, вот и выходит, что даже для хранения пути (255 сиволов) нужно уже 1020 байтиков
вот такие дела
Далее если убрать упомянутые вами индексы, то сканирование и вообще работа SOPDS будет происходить крайне медленно.
Last Edit: 6 years 3 months ago by mitshel.

Please Войти or Create an account to join the conversation.

  • mitshel
  • mitshel's Avatar
  • Offline
  • Администратор
  • Администратор
More
Time to create page: 0.211 seconds