Django South - la tabla ya existe

188

Estoy tratando de comenzar con el sur. Tenía una base de datos existente y agregué South ( syncdb, schemamigration --initial).

Luego, actualicé models.pypara agregar un campo y corrí ./manage.py schemamigration myapp --auto. Parecía encontrar el campo y dijo que podía aplicar esto con ./manage.py migrate myapp. Pero hacer eso dio el error:

django.db.utils.DatabaseError: table "myapp_tablename" already exists

tablenamees la primera tabla que aparece en models.py.

Estoy ejecutando Django 1.2, South 0.7

Steve
fuente

Respuestas:

311

Como ya tiene las tablas creadas en la base de datos, solo necesita ejecutar la migración inicial como falsa

./manage.py migrate myapp --fake

asegúrese de que el esquema de los modelos sea el mismo que el esquema de las tablas en la base de datos.

Ashok
fuente
1
Gracias. En realidad es migrar y no un esquema de migración, pero su respuesta me llevó en la dirección correcta.
Steve
1
mi error simplemente copió el comando de OP, comando correcto ./manage.py migrate myapp --fake
Ashok
Esta solución no resolvió el problema en mi caso. No modifiqué la base de datos y bloqueé algunas vistas porque el campo no se creó en la tabla. Tuve que comentar la nueva propiedad, migrar con falso nuevamente para restablecer todo, y la segunda vez que lo intenté funcionó, lo que todavía no entiendo ... :)
Mc-
1
@Ashok tal vez también deberías especificar que tenemos que rehacer un schemamigrationantes migrateen caso de que ya hayamos hecho modificaciones antes del último schemamigration.
Pierre de LESPINAY
3
Esto no me ayudó. Ya tenía una tabla en mi base de datos, y después de fingir la migración, no había forma de agregar las otras tablas que eran falsas. Tuve que dejar todas las mesas y empezar de nuevo.
Shailen
41

Aunque la tabla "myapp_tablename" ya existe, el error deja de aparecer después de que hice ./manage.py migrate myapp --fake, DatabaseError no muestra esa columna: myapp_mymodel.added_field.

¡Tengo exactamente el mismo problema!

1. Primero verifique el número de migración que está causando esto. Supongamos que es: 0010.

2. Necesita:

./manage.py schemamigration myapp --add-field MyModel.added_field
./manage.py migrate myapp

Si falta más de un campo, debe repetirlo para cada campo.

3.Ahora aterrizas con un montón de nuevas migraciones, así que elimina sus archivos de myapp / migrations (0011 y más si necesita agregar múltiples campos).

4.Ejecute esto:

./manage.py migrate myapp 0010

Ahora intente ./manage.py migrate myapp

Si no falla, estás listo. Simplemente verifique si no falta ningún campo.

EDITAR:

Este problema también puede ocurrir cuando tiene una base de datos de producción para la cual instala South y la primera migración inicial creada en otro entorno duplica lo que ya tiene en su base de datos. La solución es mucho más fácil aquí:

  1. Falsifica la primera migración:

    ./manage migrate myapp 0001 --fake

  2. Rodar con el resto de las migraciones:

    ./manage migrate myapp

pielgrzym
fuente
10

Cuando me encontré con este error, tenía una causa diferente.

En mi caso, South había dejado de alguna manera en mi DB una tabla vacía temporal, que se usa en _remake_table () . Probablemente había abortado una migración de una manera que no debería haber hecho. En cualquier caso, cada nueva migración posterior, cuando se llama _remake_table (), estaba lanzando el error sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, ya que no existe ya y no se suponía que estar allí.

La parte nueva me pareció extraña, así que examiné mi DB, vi la mesa _south_new_myapp_mymodel, me rasqué la cabeza, miré la fuente de South , decidí que era basura, dejé caer la mesa y todo estuvo bien.

autor de ben
fuente
Esto es lo que vi, y si hubiera encontrado esto, me habría ahorrado media hora de brainache. Bastante desagradable, pero estas son tablas de migración temporales y se dejan durante una migración fallida, probablemente con fines de inspección. El mío ocurrió debido a algún problema de integridad de db durante el intento de migración.
Danny Staple
¡Esto necesita estar más arriba! Si está utilizando una base de datos sin transacciones de esquema, esto puede suceder con bastante facilidad
Yuji 'Tomita' Tomita
2

Si tiene problemas con sus modelos que no coinciden con su base de datos, como @pielgrzym, y desea migrar automáticamente la base de datos para que coincida con el último archivo models.py (y borrar los datos que no serán recreados por los accesorios durante migrate):

manage.py schemamigration myapp --initial
manage.py migrate myapp --fake
manage.py migrate myapp zero
manage.py migrate myapp

Esto solo eliminará y recreará las tablas de la base de datos que existen en su último models.pyarchivo, por lo que puede tener tablas de basura en su base de datos de syncdbs o migrates anteriores. Para deshacerse de ellos, preceda todas estas migraciones con:

manage.py sqlclear myapp | manage.py sqlshell

Y si eso todavía deja algo de CRUFT en su base de datos, entonces tendrá que hacer inspectdby crear el models.pyarchivo a partir de eso (para las tablas y la aplicación que desea borrar) antes de hacer sqlcleary luego restaurar sus modelos originales.py antes creando la --initialmigración y migrando a ella. Todo esto para evitar perder el tiempo con el sabor particular de SQL que necesita su base de datos.

encimeras
fuente
1

Perform these steps in order may help you:

1) python manage.py schemamigration apps.appname --inicial

El paso anterior crea la carpeta de migración como predeterminada.

2) python manage.py migrate apps.appname --fake

genera una migración falsa

3) python manage.py schemamigration apps.appname --auto

Luego puede agregar campos como desee y ejecutar el comando anterior.

4) python manage.py migrate apps.appname

Vijesh Venugopal
fuente
1

Si tiene una base de datos y una aplicación existentes, puede usar el comando de conversión sur

./manage.py convert_to_south myapp

Esto debe aplicarse antes de realizar cambios en lo que ya está en la base de datos.

El comando convert_to_south solo funciona completamente en la primera máquina en la que lo ejecuta. Una vez que haya confirmado las migraciones iniciales que realizó en su VCS, deberá ejecutar ./manage.py migrate myapp 0001 --fakeen cada máquina que tenga una copia de la base de código (asegúrese de que estén actualizadas con los modelos y el esquema primero). ref: http://south.readthedocs.org/en/latest/convertinganapp.html

Tommy Strand
fuente
0

Como solución temporal, puede comentar la creación de la tabla en el script de migración.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

    operations = [
        #migrations.CreateModel(
        #    name='TABLE',
        #    fields=[
        #            ....
        #            ....
        #    ],
        #),
        ....
        ....

O

Si la tabla existente no contiene filas (vacías), considere eliminar la tabla como se muestra a continuación. (Esta solución se recomienda solo si la tabla no contiene filas) . Asegúrese también de esta operación antes de la operación createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]
SuperNova
fuente
0

Una solución más (quizás una solución temporal).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

p.ej.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Esto enumerará todas las migraciones en consultas SQL sin procesar. Puede elegir las consultas que desea ejecutar evitando la parte que crea la tabla existente

SuperNova
fuente