web-dev-qa-db-ja.com

Django移行エラー:列が存在しません

Python 3、Django 1.8.5、Postgres

正常に動作しているモデルSitesがあります。私は最近、airport_codeフィールドを追加して、データを移行しようとしました。

class Site(BaseModel):

  objects = SiteManager()

  name = models.CharField(max_length=200, unique=True)
  domain = models.CharField(max_length=200, unique=True)
  weather = models.CharField(max_length=10)
  nearby_sites = models.ManyToManyField('self', symmetrical=False, blank=True)
  users = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
  facebook = models.URLField(max_length=200)
  Twitter = models.URLField(max_length=200)
  header_override = models.TextField(blank=True)
  email_header_override = models.TextField(blank=True)
  timely_site_tag_id = models.IntegerField()
  timely_featured_tag_id = models.IntegerField()
  timely_domain = models.CharField(max_length=255)
  sitemap_public_id = models.CharField(max_length=255)
  state = models.CharField(max_length=24)
  airport_code = JSONField()

しかし、makemigrationsを実行するとエラーが発生しました。

Django.db.utils.ProgrammingError: column sites_site.airport_code does not exist LINE 1: ..._site"."sitemap_public_id", "sites_site"."state", "sites_sit...

もちろん、これは意味がありません。マイグレーション内で列を作成しようとしているときに、列が明らかに存在しないためです。

スタックオーバーフローに関するこのバグについて、未回答の質問を多数見かけたり、移行ファイルを手動で作成したり、データベースを破棄して再構築したりするための解決策があります。これは大丈夫な解決策ではありません。

23
Alex

このバグは、settings.pyのINSTALLED_APPSからDjangoデバッグツールバーをコメントアウトすることで解決されました。デバッグツールバーが原因である理由はわかりませんが、コメントアウトした後、 makemigrationsおよびmigrateを問題なく実行します。

私がそれを理解しようと12時間費やしたので、これが誰かを助けることを願っています。

11
Alex

Makemigrationsを実行した後、必ずスタックトレースを1つずつ実行してください。

私の場合、まったく異なるアプリのforms.pyに含まれているFormへの呼び出しを介してトレースされていることに気付きました。たまたま、新しい移行を作成しようとしているモデルへの呼び出しがありました。

Formクラスをforms.pyからviews.pyに移動すると、問題が修正されました。

14
Nexus

私の場合は、unique_together制約が設定されていたためです。

フィールドを削除したい場合、自動生成された移行では、unique_together制約を削除する前にフィールドを削除しようとしました。

私がしなければならなかったのはマイグレーションファイル内のmigrations.AlterUniqueTogether制約を手動で上に移動するなので、Djangoは、フィールドを削除する前にまず制約を削除します。

これが誰かの役に立つことを願っています。

7
darksider

私もこの問題に遭遇し、@ Nexusの回答が役に立ちました。問題の原因をより明確に説明するために、ここで特定のケースの詳細を提供すると思いました。私には潜在的なバグのようです。

次のようなモデルBrandがあります。

class Brand(BaseModelClass):
    name = CharField(max_length=256, unique=True)
    website = ForeignKey(URL, on_delete=CASCADE, null=True, blank=True)

私はpython manage.py makemigrationsBooleanフィールドを次のように追加した後:

class Brand(BaseModelClass):
    name = CharField(max_length=256, unique=True)
    website = ForeignKey(URL, on_delete=CASCADE, null=True, blank=True)
    trusted = Boolean(default=True)

makemigrationsコマンドを実行すると、OPと同様のエラーを受け取りました。

Django.db.utils.ProgrammingError: column appname_brand.trusted does not exist

@Nexus 'の提案に従い、Djangoの主要な問題ではないと想定して、スタックトレースを1行ずつ実行しました。結局のところ、アプリの1つでforms.pyファイル次のものを用意しました。

choices={(str(brand.id), brand.name) for brand in Brand.objects.all()}

解決策は、その行を単にコメント化してmanage.py makemigrations、次にmanage.py migrate。その後、その行のコメントを外し、すべての機能とフォームの機能は以前と同じように機能しました。

5

Postgresデータベースを別のサーバーに移行した後で、この問題が発生します。どういうわけか私はデータベースをめちゃくちゃにし、新しいクラスUserProfileでモデルを更新できませんでした。

既存のスキーマの初期移行を作成する問題を解決しました:

  1. Django_migrationsテーブルを空にします:delete from Django_migrations;コマンドでDELETE FROM Django_migrations WHERE app='my_app';
  2. すべてのアプリについて、そのmigrationsフォルダを削除します:rm -rf <app>/migrations/
  3. 「組み込み」アプリの移行をリセット:python manage.py migrate --fake
  4. アプリを実行するたびに:python manage.py makemigrations <app>。依存関係に注意してください(ForeignKeyを含むモデルは、親モデルの後に実行する必要があります)。
  5. 最後に:python manage.py migrate --fake-initial

ここにそれを手に入れました: https://stackoverflow.com/a/2989848

PSこれが問題の解決に関連していたかどうかはわかりませんが、最初に、エラーを引き起こしたpostgresqlのテーブルを削除し、モデルのUserProfileクラスをコメント化しました。

シェル:

 Sudo -su postgres
 psql databse_name   
 DROP TABLE table_name;

models.py:

#class UserProfile(models.Model):
    #user = models.OneToOneField(settings.AUTH_USER_MODEL, unique=True, primary_key=True, on_delete=models.CASCADE, related_name='user_profile')
    #avatar = ThumbnailerImageField(upload_to='profile_images', blank=True)
    #country = models.CharField(max_length = 128)
1
bilbohhh

同じ問題(列が存在しない)が発生しましたが、migrateではなくmakemigrationsを実行しようとすると

  • 原因:最後の変更の移行を実行する前に、移行ファイルを削除し、それらを単一の偽の初期移行ファイル0001に置き換えました

  • 解決:

    1. そのアプリの移行に関連するテーブルを削除します(バックアップの回避策があれば検討します)
    2. 移行が記録されているテーブルDjango_migrationsから、そのアプリの移行を担当する行を削除します。これは、Django=どの移行が適用され、どの移行がまだ適用される必要があるかを知る方法です。

そして、これがこの問題をどのように解決するかです:

  • postgresユーザーとしてログインします(私のユーザーはposgresと呼ばれます):

    Sudo -i -u postgres

  • SQLターミナルを開き、データベースに接続します。

    psql -d database_name

  • テーブルを一覧表示し、そのアプリに関連するテーブルを見つけます。

    \dt

  • それらをドロップします(関係のあるドロップ順序を考慮してください)。

    DROP TABLE tablename ;

  • 移行レコードを一覧表示すると、適用された移行が次のように分類されます。

id |アプリ|名前|適用された
-+ ------ + -------- + --------- +

SELECT * FROM Django_migrations;
  • そのアプリの移行の行を削除します(IDまたはアプリごとに削除できます。アプリでは「引用符」を忘れないでください)。

    DELETE FROM Django_migrations WHERE app='your_app';

  • ログアウトしてマイグレーションを実行します(場合によってはmakemigrationsを実行します)。

    python manage.py migrate --settings=your.settings.module_if_any

注:場合によっては、そのアプリのすべてのテーブルを削除する必要はなく、すべての移行を削除する必要はありません。問題を引き起こしているモデルのテーブルのみを削除する必要があります。

これがお役に立てば幸いです。

1
Yahya Yahyaoui

Django 1.11にアップグレードした後、この問題に遭遇しました。この問題に恒久的に対処したかったので、テーブルで移行を実行するたびにコードをコメント/コメント解除する必要はありません。私のアプローチ:

from Django.db.utils import ProgrammingError as AvoidDataMigrationError

try:
    ... do stuff that breaks migrations
except AvoidDataMigrationError:
    pass

インポート中の例外の名前をAvoidDataMigrationErrorに変更したので、例外が存在する理由は明らかです。

1
Jeff Bauer

必要なフィールドを実際に含むようにSingletonModelを移行しようとしたときに、今ちょうど同じエラーが発生しました。

エラーの理由は、モデルAがこのSingletonModelのいくつかのフィールドを(構成可能な値として)使用したことです。また、移行プロセス中のモデルAのインスタンス化中に、私の移行が安全であることを保証することはできませんでした。

同僚には素晴らしいアイデアがありました。フィールドのデフォルト値を関数呼び出しにし、そのために遅延させます。

例:

class A (models.Model):
    default_value = models.DecimalField(default: lambda: SingletonModel.get_solo().value, ...)

そのため、私のアドバイス:問題のある呼び出し(スタックトレースに表示されます)を遅延呼び出しにしてみてください。

1
MrKickkiller

パーティーに遅れましたが、共有したい情報がいくつかあります。とても助かりました! :)

Django-solo を使用してアプリの構成をデータベースに保存していますが、構成モデルに新しいフィールドを追加すると、Alexと同じ問題が発生しました。 Stacktraceは、データベースから構成を取得している行を示しました:conf = SiteConfiguration().get_solo()

GithubのDjango-soloプロジェクトには 終了した問題 があります。アイデアは、モデルの読み込みを遅延させることです(MrKickkillerが以前指摘したとおり)。

したがって、モダンDjangoバージョン(私の場合は3.0))の場合、このコードは完全に機能します。

from Django.utils.functional import SimpleLazyObject
conf = SimpleLazyObject(SiteConfiguration.get_solo)
1
Pantone877

アプリケーションをロードするときにクエリを実行していないことを確認してください!など。に:

class A:
  field = fn_that_makes_query()

migrateまたはmakemigrationsを実行すると、Djangoはアプリケーション全体をロードするシステムチェックを実行するため、このプロセス中に追加/変更されたクエリを使用すると、まだ存在しないdbフィールドにアクセスしようとしているため、矛盾が発生するdbフィールド。

1
nveo

最近この問題に巻き込まれました。

私の場合、コードに存在しないフィールドへの参照を追加してから、モデルファイルにアクセスして新しいフィールドを追加し、上記のエラーをスローするmakemigrationsコマンドを実行しようとしました。

そのため、スタックトレースを最後まで調べたところ、新しく追加された参照が問題であることがわかりました。とコメントし、makemigrationsとvoilaを実行しました。

0
Shobi

私は同じ問題を抱えています、これが私のケースです:アプリでMyAppモデルに新しいフィールドを追加します:

class Advisors(models.Model):
    AdvID = models.IntegerField(primary_key=True)
    Name = models.CharField(max_length=200,null=False)
    ParentID = models.IntegerField(null=True) # <--- the NEW field I add

だから私がしたことは:urls.py of MyProject、NOT MyAppMyAppにリンクされたurl()をコメント化して、makemigrationsを実行し、migrateはすべて実行されます上手; MyApp/urls.pyファイル:

urlpatterns = [
    url(r'^admin/', admin.site.urls, name='admin'),
    url(r'^$', views.HomePage.as_view(),name='home'),
    #comment out the following line, after migrate success, bring it back;
    # url(r'^myapp/', include('myapp.urls',namespace='research')), <--- 
]
0
Cat_S

私の場合、カスタムAdminSiteMyModel.objects.filterアプリケーションstartで、makemigrationsおよびmigrateデータベースに対してそれを無効にしました。

0
Serg Smyk

私もpython manage.py makemigrations app1のようなコマンドを実行したときに同じ問題が発生しました。ビューの下で別のapp2で実行されているカスタムormsにコメントすることで問題を解決しました。

例:

inside app1models.py

class ModelA(models.Model):
    subject = models.CharField(max_length=1)
    course = models.CharField(max_length=1)

inside app2view.py

# obj = ModelA.object.all()
# get_subjct = [s.subject for s in obj]

だからここで私は上記のコードにコメントし、makemigrationsを実行して移行してからコメントを外しました。

正常に動作しています...

0
santhosh_dj