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'
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top