문제

찾은 가이드를 사용하여 테스트 블로그를 만들고 있습니다. 여기.꽤 포괄적입니다.그러나 Alembic 마이그레이션에 문제가 있습니다.모든 버전을 지우고 모든 열이 정상적으로 포함된 새 데이터베이스를 가동할 수 있습니다.그런데 새 열을 추가하면 문제가 발생합니다.내 코드는 다음과 같습니다. 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()

그것은 모두 꽤 표준적입니다.그러나 다음과 같이 People 테이블에 임의의 열을 추가하려는 경우:

class Person(db.Model):
    ....
    random_column = db.Column(db.Integer())

그런 다음 실행 python manage.py db migrate (잘 작동합니다) 다음을 실행하십시오 python manage.py db upgrade 그러면 다음 오류가 발생합니다.

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' {}

스택 추적에서 생성한 열의 이름도 언급되지 않으므로 다른 테이블에 문제가 있다고 믿게 됩니다.인덱스 삭제에 대한 언급이 있지만 마이그레이션에서는 그런 작업을 수행하지 않고 단지 인덱스에 열을 추가하는 것뿐입니다. People 테이블.내가 이해하지 못하는 증류기의 무언가인가요?

내가 말했듯이 새로운 데이터베이스를 가동하고 구성을 로드하면 완벽하게 작동합니다.변경을 하고 Alembic을 마이그레이션하려고 할 때만 이러한 오류가 발생합니다.왜 이런 일이 일어나는지 아는 사람이 있나요?

편집하다

사람들이 내 모습을 봐야 할 경우를 대비해 config.py 파일:

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'
도움이 되었습니까?

해결책

나는 팔로우했다 문서 링크 Flask-Migrate에서 alembic을 어떻게 사용하는지 확인하면 다음과 같이 표시됩니다.

migration 명령은 새로운 마이그레이션 스크립트를 추가합니다.Alembic은 모델에 대한 모든 변경 사항을 감지 할 수 없으므로 검토하고 정확하게 편집해야합니다.특히 인덱스를 감지하지 않으므로 스크립트에 수동으로 추가해야합니다.

Flask-Migrate는 "자동 생성"이라는 alembic 기능을 사용합니다. 여기서는 데이터베이스 상태를 모델과 비교하고 자동으로 차이점을 생성합니다.

우리는 Alembic을 직접 사용하고 자동 생성이 정말 편리하다는 것을 알았습니다. 하지만 특히 인덱스와 제약 조건을 처리할 때 수동으로 편집해야 하는 경우가 많습니다.

그래서 내 해결책은 명시된 대로 마이그레이션 파일을 직접 편집하고 원하지 않거나 가짜 줄을 제거하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top