Alembic-Migrationsfehler Kolben
-
21-12-2019 - |
Frage
Ich erstelle einen Testblog mit der gefundenen Anleitung Hier.Es ist ziemlich umfassend.Allerdings habe ich Probleme mit den Destillierkolbenmigrationen.Ich kann alle Versionen löschen und eine neue Datenbank mit allen Spalten erstellen.Aber wenn ich eine neue Spalte hinzufüge, treten Probleme auf.Hier ist der Code in meinem models.py
:
models.py
....
class Person(db.Model):
__tablename__ = 'person'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
pwdhash = db.Column(db.String(100))
name = db.Column(db.String(100), unique=True)
def __init__(self, email, name, password):
self.email = email
self.name = name.title()
self.set_password(password)
def __repr__(self):
return '<User %r>' % (self.name)
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
@classmethod
def all(cls):
return Person.query.all()
class Category(db.Model):
__tablename__ = 'category'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
description = db.Column(db.Text)
def __unicode__(self):
return self.name
class Article(db.Model):
__tablename__ = 'articles'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
body = db.Column(db.Text)
created = db.Column(db.DateTime, default=datetime.datetime.now)
category_name = db.Column(db.String(10), db.ForeignKey(Category.name))
category = db.relationship(Category)
person_name = db.Column(db.String(100), db.ForeignKey(Person.name, onupdate="CASCADE", ondelete="CASCADE"))
person = db.relationship(Person)
@property
def slug(self):
return urlify(self.title)
@classmethod
def all(cls):
return Article.query.order_by(desc(Article.created)).all()
@classmethod
def find_by_category(cls, category):
return Article.query.filter(Article.category_name == category).all()
Es ist alles ziemlich normal.Wenn ich jedoch eine zufällige Spalte zu meiner Personentabelle hinzufügen würde, würde das folgendermaßen aussehen:
class Person(db.Model):
....
random_column = db.Column(db.Integer())
Führen Sie dann a aus python manage.py db migrate
(was gut funktioniert) und dann a ausführen python manage.py db upgrade
dann erhalte ich folgende Fehlermeldung:
Traceback (most recent call last):
File "manage.py", line 7, in <module>
manager.run()
File "/Library/Python/2.7/site-packages/flask_script/__init__.py", line 397, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/Library/Python/2.7/site-packages/flask_script/__init__.py", line 376, in handle
return handle(app, *positional_args, **kwargs)
File "/Library/Python/2.7/site-packages/flask_script/commands.py", line 145, in handle
return self.run(*args, **kwargs)
File "/Library/Python/2.7/site-packages/flask_migrate/__init__.py", line 82, in upgrade
command.upgrade(config, revision, sql = sql, tag = tag)
File "/Library/Python/2.7/site-packages/alembic/command.py", line 124, in upgrade
script.run_env()
File "/Library/Python/2.7/site-packages/alembic/script.py", line 199, in run_env
util.load_python_file(self.dir, 'env.py')
File "/Library/Python/2.7/site-packages/alembic/util.py", line 198, in load_python_file
module = load_module(module_id, path)
File "/Library/Python/2.7/site-packages/alembic/compat.py", line 55, in load_module
mod = imp.load_source(module_id, path, fp)
File "migrations/env.py", line 72, in <module>
run_migrations_online()
File "migrations/env.py", line 65, in run_migrations_online
context.run_migrations()
File "<string>", line 7, in run_migrations
File "/Library/Python/2.7/site-packages/alembic/environment.py", line 652, in run_migrations
self.get_context().run_migrations(**kw)
File "/Library/Python/2.7/site-packages/alembic/migration.py", line 225, in run_migrations
change(**kw)
File "migrations/versions/4171a9f6ed2a_.py", line 19, in upgrade
op.drop_index('category_name_key', 'category')
File "<string>", line 7, in drop_index
File "<string>", line 1, in <lambda>
File "/Library/Python/2.7/site-packages/alembic/util.py", line 293, in go
return fn(*arg, **kw)
File "/Library/Python/2.7/site-packages/alembic/operations.py", line 716, in drop_index
self._index(name, table_name, ['x'], schema=schema)
File "/Library/Python/2.7/site-packages/alembic/ddl/impl.py", line 164, in drop_index
self._exec(schema.DropIndex(index))
File "/Library/Python/2.7/site-packages/alembic/ddl/impl.py", line 76, in _exec
conn.execute(construct, *multiparams, **params)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 662, in execute
params)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 720, in _execute_ddl
compiled
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 874, in _execute_context
context)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 1024, in _handle_dbapi_exception
exc_info
File "/Library/Python/2.7/site-packages/sqlalchemy/util/compat.py", line 196, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 867, in _execute_context
context)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/default.py", line 324, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.InternalError: (InternalError) cannot drop index category_name_key because constraint category_name_key on table category requires it
HINT: You can drop constraint category_name_key on table category instead.
'\nDROP INDEX category_name_key' {}
Der Name der Spalte, die ich im Stacktrace erstellt habe, wird nicht einmal erwähnt, sodass ich vermute, dass mit den anderen Tabellen etwas nicht stimmt.Es wird das Löschen eines Index erwähnt, aber ich mache so etwas bei der Migration nicht, sondern füge nur eine Spalte hinzu People
Tisch.Ist es etwas im Destillierkolben, das ich nicht verstehe?
Wie gesagt, es funktioniert perfekt, wenn ich eine brandneue Datenbank hochfahre und die Konfiguration lade.Erst wenn ich eine Änderung vornehme und versuche zu migrieren, meldet mir Alembic diese Fehler.Hat jemand eine Idee, warum das passiert?
BEARBEITEN
Nur für den Fall, dass die Leute mich sehen müssen config.py
Datei:
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
#-----Config the app
SECRET_KEY = 'my_key'
CSRF_ENABLED = True
#-----Config Database
SQLALCHEMY_DATABASE_URI = 'postgresql://username:changeme@localhost/test'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
#-----Config Upload folder
UPLOAD_FOLDER = os.path.realpath('./snb/static') + '/uploads'
Lösung
ich folgte der Link zum Dokument auf Flask-Migrate, um zu sehen, wie es Alembic verwendet, und es heißt:
Der Migrationsbefehl fügt ein neues Migrationsskript hinzu.Sie sollten es überprüfen und so zu genau bearbeiten, da Alembic nicht alle Änderungen an Ihren Modellen erkennen kann.Insbesondere erkennt es keine Indizes, daher müssen diese manuell zum Skript hinzugefügt werden.
Flask-Migrate verwendet eine Funktion von Alembic namens „Autogenerate“, bei der versucht wird, den Status Ihrer Datenbank mit Ihren Modellen zu vergleichen und automatisch ein Diff zu erstellen.
Wir verwenden Alembic direkt und ich fand die automatische Generierung sehr praktisch, aber ich muss sie häufig manuell bearbeiten, insbesondere wenn es um Indizes und Einschränkungen geht.
Meine Lösung wäre also, das zu tun, was es sagt, die Migrationsdatei manuell zu bearbeiten und die Zeilen zu entfernen, die Sie nicht möchten oder die falsch sind.