Python 向模型添加字段后“没有这样的列”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36053014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 17:20:28  来源:igfitidea点击:

"no such column" after adding a field to the model

pythondjango

提问by ming

environment DJANGO VERSION 1.9 Python 2.7.6

环境 DJANGO 版本 1.9 Python 2.7.6

I added a field (scores) to a model class in models.py like this

我像这样在 models.py 中的模型类中添加了一个字段(分数)

from django.db import models
from django.contrib.auth.models import User
import urllib
import hashlib


class profile(models.Model):
    user = models.OneToOneField(User)
    nickname = models.CharField(max_length=12, blank=True, null=True)
    use_gravatar = models.BooleanField(default=True)
    location = models.CharField(max_length=20, blank=True, null=True)
    avatar_url = models.URLField(blank=True, null=True)
    website = models.URLField(blank=True, null=True)
    **scores = models.IntegerField(default = 0)**  

and I run the following commands to sync the database.

我运行以下命令来同步数据库。

python manage.py makemigrations
python manage.py migrate

But got this

但是得到了这个

OperationalError at /
no such column: account_profile.scores
Request Method: GET
Request URL:    http://127.0.0.1:8000/
Django Version: 1.8.4
Exception Type: OperationalError
Exception Value:    
no such column: account_profile.scores
Exception Location: C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py in execute, line 318
Python Executable:  C:\Python27\python.exe
Python Version: 2.7.5
Python Path:    
['c:\FairyBBS',
 'C:\Users\user\AppData\Roaming\Python\Python27\site-packages\setuptools-5.4.1-py2.7.egg',
 'C:\Users\user\AppData\Roaming\Python\Python27\site-packages\urlobject-2.4.0-py2.7.egg',
 'C:\Users\user\AppData\Roaming\Python\Python27\site-packages\djangorestframework-0.4.0-py2.7.egg',
 'C:\WINDOWS\SYSTEM32\python27.zip',
 'C:\Python27\DLLs',
 'C:\Python27\lib',
 'C:\Python27\lib\plat-win',
 'C:\Python27\lib\lib-tk',
 'C:\Python27',
 'C:\Users\user\AppData\Roaming\Python\Python27\site-packages',
 'C:\Python27\lib\site-packages']
Server time:    星期四, 17 三月 2016 14:08:04 +0800

回答by itzMEonTV

Fast fix.

快速修复。

First remove field scores, Then

首先删除字段scores,然后

python manage.py makemigrations
python manage.py migrate

If any error happens

如果发生任何错误

python manage.py migrate --fake

Then add field scores.Then

然后添加字段scores。然后

python manage.py makemigrations
python manage.py migrate

Hope this helps.

希望这可以帮助。

回答by Adwaith

This can happen if you are referencing your model at the root level of your app

如果您在应用程序的根级别引用模型,则可能会发生这种情况

This happened to me when I was updating the app mapping_master. I was adding a new field like so:

当我更新应用程序mapping_master时,这发生在我身上。我正在添加一个新字段,如下所示:

class MappingMaster(models.Model):

    ...

    # New field that was being added
    statement = models.CharField(max_length=20, choices=STATEMENT_CHOICES, default='PNL', blank=True, null=True)

Gave me the following stacktrace:

给了我以下堆栈跟踪:

D:\Adwaith\codebase\unitapp>python manage.py makemigrations
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line
338, in execute_from_command_line
    utility.execute()
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line
312, in execute
    django.setup()

....
....

  File "C:\Python27\lib\site-packages\django\apps\config.py", line 198, in impor
t_models
    self.models_module = import_module(models_module_name)
  File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "D:\Adwaith\codebase\unitapp\trial_balance_entry\models.py", line 5, in <
module>
    from unitapp import docclass
  File "D:\Adwaith\codebase\unitapp\unitapp\docclass.py", line 139, in <module>
    sample_train_type(type_classifier)
  File "D:\Adwaith\codebase\unitapp\unitapp\docclass.py", line 6, in sample_trai
n_type
    for mapping in MappingMaster.objects.all():

....
....

  File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line
318, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such column: mapping_master_mappingmaster.statement

Turns out that my problem was in another file entirely. It was in the trial_balance_entryapp:

原来我的问题完全在另一个文件中。它在trial_balance_entry应用程序中:

...
# The important line is below
from unitapp import docclass


class TrialBalanceEntry(models.Model):
    ...

And inside docclass.py, I had:

在 docclass.py 中,我有:

import re, csv, os
from mapping_master.models import MappingMaster


def sample_train_type(cl):
    for mapping in MappingMaster.objects.all():
        cl.train(mapping.entry, mapping.type)


def sample_train_category(cl):
    for mapping in MappingMaster.objects.all():
        cl.train(mapping.entry, mapping.category)

...

Turns out that the MappingMaster model instances were being referenced at the root of the app (since I imported it at the start of the file in the models file in trial_balance_entry.

结果是 MappingMaster 模型实例在应用程序的根目录中被引用(因为我在trial_balance_entry的模型文件中的文件开头导入了它。

I fixed that by moving the import to one of the inner methods of my TrialBalanceEntrymodel. This made sure I didn't have any hidden circular dependencies.

我通过将导入移动到我的TrialBalanceEntry模型的内部方法之一来解决这个问题。这确保我没有任何隐藏的循环依赖。

P.S. From next time, please provide a stacktrace from the console so we can debug it more easily.

PS 从下一次开始,请提供来自控制台的堆栈跟踪,以便我们可以更轻松地调试它。

回答by Shosalim Baxtiyorov

Well the problem is NOTwith your makemigrations command or models.py. It is because you have probably imported your class in the model (your database in this case) in on of your views.py files and the problem is with that. If you read the all of the error message then you can understand that easily.

那么问题在于您的 makemigrations 命令或 models.py。这是因为您可能已经在 views.py 文件中的模型(在本例中为您的数据库)中导入了您的类,问题就在于此。如果您阅读了所有错误消息,那么您可以轻松理解。

Just try commenting that importing part and run your python.manage.py makemigrationsand python manage.py migratecommands then you can uncomment your importin your views.py file

只需尝试注释该导入部分并运行您的python.manage.py makemigrationspython manage.py migrate命令,然后您就可以import在您的 views.py 文件中取消注释

Hope this was useful for others as well

希望这对其他人也有用

回答by Schlauewurst

Easyes Solution: RENAME the field makemigrations migrate RENAME back makemigrations migrate

Easyes 解决方案:RENAME 字段 makemigrations migrate RENAME back makemigrations migrate

回答by Block2busted

All, that u need: download ?DB Browser for SQLite? and:

所有,你需要的:下载 SQLite 的数据库浏览器?和:

  1. Copy your ‘db.sqlite3' to different Folder.
  2. Delete your ‘db.sqlite3'.
  3. Run ‘python3 manage.py make migrations', then ‘python3 manage.py migrate'.
  4. Open your new ‘db.sqlite3' in ?DB Browser for SQLite? and find table ‘account_profile'
  5. Then do like 1st image. U should export ‘account-profile' table to CSV file.
  6. Delete your new ‘db.sqlite3' and return you old ‘db.sqlite3'
  7. Open your DB in ?DB Browser for SQLite?, then ?File—>Import—>Tables from file CSV..? and choose ‘account_profile.csv'
  8. Then U will see, that in this table u should change columns ‘field1' to ‘id' and ‘field2' to ‘user_id'. I did it on 2nd and 3rd images.
  9. Last, what should u do: Look at ‘id' of your admin in the table ‘auth_user' and change on this value in the ‘account_profile table'
  10. Delete your Admin-Model in DB(auth_user table)
  1. 将您的“db.sqlite3”复制到不同的文件夹。
  2. 删除你的“db.sqlite3”。
  3. 运行“python3 manage.py make migrations”,然后运行“python3 manage.py migrate”。
  4. 在 ?DB Browser for SQLite 中打开新的 'db.sqlite3'?并找到表“account_profile”
  5. 然后像第一个图像一样。您应该将“帐户配置文件”表导出为 CSV 文件。
  6. 删除新的 'db.sqlite3' 并返回旧的 'db.sqlite3'
  7. 在 ?DB Browser for SQLite? 中打开你的数据库,然后 ?File—>Import—>Tables from file CSV..?并选择“account_profile.csv”
  8. 然后你会看到,在这个表中你应该将“field1”列更改为“id”,将“field2”列更改为“user_id”。我在第二张和第三张图片上做了。
  9. 最后,您应该怎么做:查看“auth_user”表中管理员的“id”并更改“account_profile 表”中的此值
  10. 删除数据库中的管理模型(auth_user 表)

Yeah, 5-10 minutes to do it, but all is work)

是的,5-10 分钟即可完成,但一切正常)

image1

图片1

image2

图像2

image3

图像3

result

结果

回答by Priyank Kodesia

Keeping it short and precise, give that field a default value.

保持简短和精确,给该字段一个默认值。

For example:

例如:

nickname = models.CharField(max_length=12, default=" ") 

and not default=True

并不是 default=True

If that doesn't work delete the migrations in your app's migration folder except

如果这不起作用,请删除应用程序迁移文件夹中的迁移,除了

__init__.py file and type both the commands again.
python manage.py migrate
python manage.py makemigrations appname
python manage.py migrate(again)

回答by Renon Lift

Those migration issues bother me too when i have to update my app with new columns, so i've made a small bash with some python to search for troublesome columns, remove them, migrate, re-add them and migrate again.

当我必须用新列更新我的应用程序时,这些迁移问题也困扰着我,所以我用一些 python 做了一个小 bash 来搜索有问题的列,删除它们,迁移,重新添加它们并再次迁移。

Here is the resolve.shthat calls python and migrations (has to be placed in the same folder as your manage.pyfile, like the .pyfiles) :

这是resolve.sh调用 python 和迁移(必须与文件放在同一文件夹中manage.py,如.py文件):

python manage.py shell < check.py

read -p "Does it seem ok ? (y for ok/n for remigrate)" migrateok

if [ $migrateok = "n" ]
then
    python manage.py shell < rm_badcolumns.py

    python manage.py makemigrations
    sleep 1
    python manage.py migrate

    python manage.py shell < resume_badcolumns.py

    python manage.py makemigrations
    sleep 1
    python manage.py migrate

    echo It should work now..
else
    echo No changes were made..
fi

check.pychecks if there are issues with some models in the database :

check.py检查数据库中的某些模型是否存在问题:

from <app>.models import *
import os, sys
from shutil import move
from django.db import connection

tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)

errorColumn = []
is_fine = "EVERYTHING LOOKS FINE!"
#looping through models to detect issues
for model in seen_models:
    try:
        print(model.objects.all())
    except:
        is_fine = "WARNING SOME MODELS ARE CORRUPTED"

print(is_fine)

This check will tell the user if some models are not sync with your database.

此检查将告诉用户某些模型是否与您的数据库不同步。

If the user chooses to "re-migrate", it calls rm_badcolumns.py:

如果用户选择“重新迁移”,它会调用rm_badcolumns.py

from <app>.models import *
import os, sys
from shutil import move
from django.db import connection


tables = connection.introspection.table_names()
seen_models = connection.introspection.installed_models(tables)

errorColumn = []

for model in seen_models:
    try:
        model.objects.all()
    except:
        errorColumn.append(str(sys.exc_info()[1])[30::]+' =')
        #this weird expression just get the column that causes trouble
        #you may have to adapt indexes depending on error output in exc_info

os.chdir('./<app>/')

#removing columns from models.py based on the error pattern
def replace(pattern, subst):
    with open('models_sub.py','w') as fout:
        with open('models.py','r') as models:
            for line in models:
                fout.write(line.replace(pattern, subst))

    os.remove('models.py')
    move('models_sub.py','models.py')

#applying this func to each error, and commenting out columns with an error mark to catch them back later
for errorStr in errorColumn:
    replace(errorStr, '#error_mark '+errorStr)

print 'Removing troublesome column for re-entering..'

Then resolve.shwill start another migration. We uncomment the troublesome columns with resume_badcolumns.pyto get them migrated again :

然后resolve.sh将开始另一个迁移。我们取消对麻烦列的注释,resume_badcolumns.py以便再次迁移它们:

from <app>.models import *
import os, sys
from shutil import move
from django.db import connection


os.chdir('./<app>/')

#same search and replace func but returning True if sthg was replaced, and False otherwise
def replace(pattern, subst):
    a = False
    with open('models_sub.py','w') as fout:
        with open('models.py','r') as models:
            for line in models:
                fout.write(line.replace(pattern, subst))
                if pattern in line:
                    a = True
    os.remove('models.py')
    move('models_sub.py','models.py')

    return a

a = True
#while error_marks are replaced, we go on looping
while a:
    a = replace('#error_mark ', '')

print 'Re-adding troublesome columns..'

We make a final migration and everything should be fine.

我们进行了最后的迁移,一切都应该没问题。

This is a kind of heavy and dirty artillery for a small problem but i wanted it to be automatized. A few points may need some rework, such as the way i identify which column is not synced, and i'd appreciate comments about this.

这是一种用于解决小问题的沉重而肮脏的大炮,但我希望它能够自动化。有几点可能需要一些返工,例如我确定哪个列未同步的方式,我很感激对此发表评论。