Преобразование существующей базы данных MyISAM в InnoDB с помощью Django - PullRequest
8 голосов
/ 11 февраля 2012

Можно ли в любом случае преобразовать полностью заполненную базу данных MyISAM в InnoDB (таким образом, чтобы создать все ограничения внешнего ключа, так же, как если бы я запускал команду syncdb с самого начала)?

Ответы [ 4 ]

5 голосов
/ 13 марта 2013

Это может помочь:

from django.core.management.base import BaseCommand
from django.db import connections


class Command(BaseCommand):

    def handle(self, database="default", *args, **options):

        cursor = connections[database].cursor()

        cursor.execute("SHOW TABLE STATUS")

        for row in cursor.fetchall():
            if row[1] != "InnoDB":
                print "Converting %s" % row[0],
                print cursor.execute("ALTER TABLE %s ENGINE=INNODB" % row[0])

Добавьте это в свое приложение в папке управления / командах / Затем вы можете преобразовать все свои таблицы с помощью команды manage.py:

python manage.py convert_to_innodb
3 голосов
/ 10 июля 2012

Преобразование MyISAM в InnoDB с помощью Django.

Учитывая, что старая база данных находится в MyISAM.

Сбросить данные старой базы данных в json с помощью:

$ python manage.py dumpdata contenttypes --indent=4 --natural > contenttype.json
$ python manage.py dumpdata --exclude contenttypes --indent=4 --natural > everything_else.json

Удалитьстарой базы данных, и создайте ее снова.

Добавьте настройки InnoDB в ваши settings.py следующим образом:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'STORAGE_ENGINE': 'InnoDB',
        'NAME': 'yourdbname',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
        'OPTIONS': {
            'init_command': 'SET storage_engine=InnoDB',  # better to set this in your database config, otherwise django has to do a query everytime
        }
    }
}

Создайте таблицы (django также добавляет отношения) Убедитесь, что вы этого не делаетедобавьте пользователя с правами администратора:

$ python manage.py syncdb --migrate

Теперь вы хотите очистить все старые таблицы:

$ python manage.py sqlflush | ./manage.py dbshell

Теперь вы можете загрузить новые данные в базу данных следующим образом:

$ python manage.py loaddata contenttype.json
$ python manage.py loaddata everything_else.json

Вот, пожалуйста.Для этого я использовал Django == 1.4.

2 голосов
/ 11 февраля 2012

Это действительно не имеет ничего общего с Джанго.Это полностью MySQL, и есть документация по этому типу вещей непосредственно от них: http://dev.mysql.com/doc/refman/5.5/en/converting-tables-to-innodb.html

1 голос
/ 13 ноября 2014

У меня была похожая ситуация, когда я не осознавал, что у моего хостинг-провайдера была такая старая версия MySQL, что по-прежнему по умолчанию использовалась MyISAM, но я уже настроил базовые таблицы Django.

Это было опубликовано примерно через 2 месяца после первоначального вопроса: Преобразовать устаревшие Django MySQL DBS из MyISAM в InnoDB .

Это и ответ пиявки / Трея описывают команду ALTER TABLE ___ ENGINE = INNODB, которая преобразует таблицу в MySQL, но проблема в том, что, хотя таблицы преобразуются, они не имеют ограничений внешнего ключа, которые были бы настроить, если таблицы были INNODB в первую очередь.

На django-admin.py и manage.py я обнаружил, что python manage.py sqlall appname "печатает операторы CREATE TABLE и SQL с начальными данными для заданных имен приложений."

Я посмотрел INSTALLED_APPS в settings.py и в итоге запустил что-то вроде python manage.py sqlall admin auth contenttypes sessions sites messages staticfiles (по одному для каждого django.contrib.appname в INSTALLED_APPS). Это показало начальные операторы CREATE TABLE, индексы и ограничения внешнего ключа:

ALTER TABLE `django_admin_log` ADD CONSTRAINT `content_type_id_refs_id_288599e6` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`);
ALTER TABLE `django_admin_log` ADD CONSTRAINT `user_id_refs_id_c8665aa` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_permission` ADD CONSTRAINT `content_type_id_refs_id_728de91f` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`);
ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `permission_id_refs_id_a7792de1` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`);
ALTER TABLE `auth_group_permissions` ADD CONSTRAINT `group_id_refs_id_3cea63fe` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`);
ALTER TABLE `auth_user_user_permissions` ADD CONSTRAINT `permission_id_refs_id_67e79cb` FOREIGN KEY (`permission_id`) REFERENCES `auth_permission` (`id`);
ALTER TABLE `auth_user_groups` ADD CONSTRAINT `group_id_refs_id_f0ee9890` FOREIGN KEY (`group_id`) REFERENCES `auth_group` (`id`);
ALTER TABLE `auth_user_user_permissions` ADD CONSTRAINT `user_id_refs_id_f2045483` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_user_groups` ADD CONSTRAINT `user_id_refs_id_831107f1` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
ALTER TABLE `auth_message` ADD CONSTRAINT `user_id_refs_id_9af0b65a` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);

После преобразования всех таблиц в ENGINE = INNODB я запустил ограничения внешнего ключа, описанные выше, и считаю, что база данных должна быть в том же состоянии, в каком она была бы, если бы моя база данных по умолчанию создавала таблицы INNODB.

Между прочим, как заметил в своем ответе Майкл ван де Ваэтер, если вы хотите, чтобы любые новые таблицы, которые Django создает по умолчанию, были INNODB, вы должны добавить 'OPTIONS': {"init_command": "SET storage_engine=INNODB",} к диктанту DATABASES в settings.py

...