2012-02-10 15 views

Respuesta

2

Esto realmente no tiene nada que ver con Django. Es completamente algo de MySQL, y hay documentación sobre este tipo de cosas directamente de ellos: http://dev.mysql.com/doc/refman/5.5/en/converting-tables-to-innodb.html

+0

es realmente? Quiero decir, las tablas MyISAM no tienen restricciones de clave externa almacenadas en sus definiciones. Django, por otro lado, tiene información sobre las relaciones de tablas, ¿no? ¿Quizás el OP está preguntando sobre una forma de convertir las tablas y al mismo tiempo agregar las FK (que corresponden a las relaciones) definidas en Django? –

+0

@ycubcube - Tienes razón, no sé por qué Chris pensó que no era adecuado para Django ... – Ohad

+1

¿En qué parte de Chris dijo que no era adecuado para Django? Él acaba de decir que migrar las tablas no tiene nada que ver con Django, lo cual es cierto. Siga sus instrucciones, y si las restricciones FK no están disponibles, puede obtenerlas con 'manage.py sqlindexes'. –

3

Conversión de MyISAM a InnoDB con Django.

Dada la base de datos anterior está en MyISAM.

volcar los datos de base de datos antigua a JSON con:

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

Eliminar la base de datos de edad, y crear de nuevo.

Añadir configuración InnoDB en su settings.py así:

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 
     } 
    } 
} 

crear tablas (Django también añade las relaciones) Asegúrese de que no se agrega un usuario administrador:

$ python manage.py syncdb --migrate 

ahora que desea vaciar todas las viejas tablas:

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

ahora puede cargar la ne w datos en la base de datos como lo siguiente:

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

Ahí lo tiene. Utilicé Django == 1.4 para esto.

+2

puede truncar todas sus tablas con ./manage.py sqlflush | ./manage.py dbshell – frog32

+0

django docs dice que se elimine el init_command cuando se haya creado su tabla, ya que agrega una consulta SQL a cada conexión de base de datos. En su lugar, cambie el tipo de tabla predeterminado en su configuración de MySQL. –

+0

Para quien viene aquí para copiar/pegar código: probablemente haya intentado esto y haya dado un error '" ERROR 1064 (42000) en la línea 1 "'. Eso es porque hubo advertencias iniciales al ejecutar 'python manage.py sqlflush'. Para eludirlo: 'python manage.py sqlflush> flushdump.txt', elimine las advertencias iniciales, guarde, y luego' python manage.py dbshell

5

Esto podría ayudar:

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]) 

añadir que a su aplicación bajo las carpetas de gestión/comandos/A continuación, puede convertir todos sus cuadros con un comando manage.py:

python manage.py convert_to_innodb 
1

que tenía una situación similar en la que no me di cuenta de que mi proveedor de hosting tenía una versión de MySQL tan antigua que todavía no funcionaba en MyISAM, pero ya había configurado las tablas básicas de Django.

Esto se publicó unos 2 meses después de la pregunta original: Convert Legacy Django MySQL DBS from MyISAM to InnoDB.

Eso y la respuesta de Leech/Trey describen el comando ALTER TABLE ___ ENGINE = INNODB que convierte la tabla en MySQL, pero el problema es que aunque las tablas se convierten, no tienen las restricciones de clave externa que tendrían sido configurado si las tablas habían sido INNODB en primer lugar.

Encontré, en django-admin.py and manage.py, que python manage.py sqlall appname "imprime las sentencias CREATE TABLE y SQL de datos iniciales para el (los) nombre (s) de la aplicación dada (s)."

Miré INSTALLED_APPS en settings.py y terminé ejecutando algo como python manage.py sqlall admin auth contenttypes sessions sites messages staticfiles (uno para cada django.contrib.appname en INSTALLED_APPS).Eso demostró la inicial CREATE TABLE, índices y claves foráneas:

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`); 

Después de convertir todas las tablas en el motor = INNODB me encontré las restricciones de clave externa por encima y por creer que debería tener la base de datos en el mismo estado en que habría sido si mi base de datos hubiera predeterminado crear tablas INNODB en primer lugar.

Por cierto, como Michael van de Waeter mencionó en su respuesta, si quieres nuevas tablas Django genere sean InnoDB por defecto, se debe añadir 'OPTIONS': {"init_command": "SET storage_engine=INNODB",} a las bases de datos de diccionario en settings.py

Cuestiones relacionadas