Django South - tabela já existe

187

Estou tentando começar com o sul. Eu tinha um banco de dados existente e adicionei Sul ( syncdb, schemamigration --initial).

Atualizei models.pypara adicionar um campo e executei ./manage.py schemamigration myapp --auto. Pareceu encontrar o campo e disse que eu poderia aplicar isso ./manage.py migrate myapp. Mas, fazer isso deu o erro:

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

tablenameé a primeira tabela listada em models.py.

Estou executando o Django 1.2, South 0.7

Steve
fonte

Respostas:

310

Como você já possui as tabelas criadas no banco de dados, basta executar a migração inicial como falsa

./manage.py migrate myapp --fake

verifique se o esquema dos modelos é igual ao esquema das tabelas no banco de dados.

Ashok
fonte
1
Entendi, obrigado. Na verdade, é migrar e não a migração de esquemas, mas sua resposta me levou na direção certa.
21410 Steve
1
meu erro acabou de copiar o comando do OP, comando correto ./manage.py migrate myapp --fake
Ashok
Esta solução não resolveu o problema no meu caso. Não modifiquei o banco de dados e troquei algumas visualizações porque o campo não foi criado na tabela. Eu tive que comentar a nova propriedade, migrar com falso novamente para restabelecer tudo, e a segunda vez que tentei funcionou, o que ainda não entendo ... :) #
09-12
1
@ Ashok, talvez você também deva especificar que precisamos refazer um schemamigrationantes do migratecaso de já termos feito modificações antes do último schemamigration.
Pierre de LESPINAY 14/12/12
3
Isso não me ajudou. Eu já tinha uma tabela no meu banco de dados e, após falsificar a migração, não havia como adicionar as outras tabelas falsificadas. Eu tive que largar todas as mesas e começar de novo.
Shailen 6/09/2013
41

Embora a tabela "myapp_tablename" já exista erro ao parar de aumentar após a migração de ./manage.py, myapp --fake, o DatabaseError não mostra essa coluna: myapp_mymodel.added_field.

Tem exatamente o mesmo problema!

1.Verifique primeiro o número da migração que está causando isso. Vamos supor que seja: 0010.

2.Você precisa:

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

se houver mais de um campo ausente, você deverá repeti-lo para cada campo.

3.Agora você chega a um monte de novas migrações, portanto remova os arquivos de myapp / migrations (0011 e mais se precisar adicionar vários campos).

Execute isso:

./manage.py migrate myapp 0010

Agora tente ./manage.py migrar myapp

Se não falhar, você está pronto. Basta verificar duas vezes se algum campo não está faltando.

EDITAR:

Esse problema também pode ocorrer quando você tem um banco de dados de produção para o qual você instala o Sul e a primeira, a migração inicial criada em outro ambiente duplica o que você já possui no seu banco de dados. A solução é muito mais fácil aqui:

  1. Fingir a primeira migração:

    ./manage migrar myapp 0001 --fake

  2. Role com o restante das migrações:

    ./manage migrar myapp

pielgrzym
fonte
10

Quando me deparei com esse erro, ele tinha uma causa diferente.

No meu caso, o Sul havia deixado de alguma forma no meu banco de dados uma tabela vazia temporária, usada em _remake_table () . Provavelmente eu havia abortado uma migração de uma maneira que não deveria. Em qualquer caso, cada nova migração posterior, quando ele chamou _remake_table (), estava jogando o erro sqlite3.pypysqlite2.dbapi2.OperationalError: table "_south_new_myapp_mymodel" already exists, porque se já existem e não deveria estar lá.

A parte _south_new parecia estranha para mim, então eu procurei no meu banco de dados, vi a mesa _south_new_myapp_mymodel, coçou a cabeça, olhei a fonte de South , decidi que era lixo, deixei a mesa cair e tudo estava bem.

autor do bem
fonte
Foi o que vi e, se o tivesse encontrado, teria me poupado meia hora de dor de cabeça. Bastante desagradável - mas essas são tabelas de migração temporárias e permanecem durante uma falha na migração, provavelmente para fins de inspeção. A mina ocorreu devido a algum problema de integridade do banco de dados durante a tentativa de migração.
9119 Danny Staple
Isso precisa ser mais alto! Se você estiver usando um db w transações esquema E / S isso pode acontecer muito facilmente
Yuji 'Tomita' Tomita
2

Se você tiver problemas com seus modelos que não correspondem ao seu banco de dados, como @pielgrzym, e deseja migrar automaticamente o banco de dados para corresponder ao arquivo models.py mais recente (e apagar todos os dados que não serão recriados pelos equipamentos durante migrate):

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

Isso excluirá e recriará apenas as tabelas de banco de dados existentes em seu models.pyarquivo mais recente ; portanto, você pode ter tabelas de lixo em seu banco de dados de syncdbs ou s anteriores migrate. Para se livrar deles, anteceda todas essas migrações com:

manage.py sqlclear myapp | manage.py sqlshell

E se isso ainda deixar alguma CRUFT no seu banco de dados, você precisará inspectdbcriar e criar o models.pyarquivo a partir dele (para as tabelas e aplicativos que deseja limpar) antes de fazer sqlcleare restaurar os modelos originais.py antes criando a --initialmigração e migrando para ela. Tudo isso para evitar mexer com o sabor específico do SQL que seu banco de dados precisa.

fogão
fonte
1

Perform these steps in order may help you:

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

A etapa acima cria a pasta de migração como padrão.

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

gera uma migração falsa.

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

Em seguida, você pode adicionar campos como desejar e executar o comando acima.

4) python manage.py migrar apps.appname

Vijesh Venugopal
fonte
1

Se você já possui um banco de dados e aplicativo, pode usar o comando de conversão sul

./manage.py convert_to_south myapp

Isso deve ser aplicado antes de você fazer alterações no que já está no banco de dados.

O comando convert_to_south funciona apenas inteiramente na primeira máquina em que você o executa. Depois de confirmar as migrações iniciais feitas no seu VCS, você precisará executar ./manage.py migrate myapp 0001 --fakeem todas as máquinas que possuem uma cópia da base de código (verifique se elas estavam atualizadas primeiro com os modelos e o esquema). ref: http://south.readthedocs.org/en/latest/convertinganapp.html

Tommy Strand
fonte
0

Como solução temporária, você pode comentar a criação da tabela no script de migração.

class Migration(migrations.Migration):

    dependencies = [
        (...)
    ]

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

Ou

Se a tabela existente não contiver linhas (vazias), considere excluir a tabela como abaixo. (Essa correção é recomendada apenas se a tabela não contiver linhas) . Verifique também se esta operação antes da operação createModel.

class Migration(migrations.Migration):

    dependencies = [
        (...),
    ]

    operations = [
        migrations.RunSQL("DROP TABLE myapp_tablename;")
    ]
Super Nova
fonte
0

Mais uma solução (talvez uma solução temporária).

$ python manage.py sqlmigrate APP_NAME MIGRATION_NAME

por exemplo.,.

$ python manage.py sqlmigrate users 0029_auto_20170310_1117

Isso listará todas as migrações em consultas sql brutas. Você pode escolher as consultas que deseja executar, evitando a parte que cria a tabela existente

Super Nova
fonte