私はいくつかのFlaskを学ぼうとしていますが、Flask-Migrate1.6.0を使用しています
なのでこんなモデルを作りました
class Download(db.Model):
__tablename__ = "downloads"
id = db.Column(db.Integer, autoincrement=True, primary_key=True)
filename = db.Column(db.String, nullable=False)
size = db.Column(db.Integer, nullable=False)
location = db.Column(db.String, nullable=False)
season = db.Column(db.Integer, nullable=False)
download_timestamp = db.Column(db.DateTime, nullable=False)
show_id = db.Column(db.Integer, ForeignKey("shows.id"))
def __init__(self,filename,size,location,timestamp,season):
self.filename = filename
self.size = size
self.location = location
self.download_timestamp = timestamp
self.season = season
def __repr__(self):
return '<File {}'.format(self.filename)
次に、この行を除いてまったく同じものに変更しました:
size = db.Column(db.BigInteger, nullable=False)
私が実行すると
manager.py db migrate
コマンドは、列タイプの変更を検出しません。そして、私はそれを読み、env.pyを変更してcompare_type = True変数を追加したときにそれを取得する必要があることを知っています。しかし、私はこれを無駄にしました、方法は今このように見えます
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
# this callback is used to prevent an auto-migration from being generated
# when there are no changes to the schema
# reference: http://alembic.readthedocs.org/en/latest/cookbook.html
def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0]
if script.upgrade_ops.is_empty():
directives[:] = []
logger.info('No changes in schema detected.')
engine = engine_from_config(config.get_section(config.config_ini_section),
prefix='sqlalchemy.',
poolclass=pool.NullPool)
connection = engine.connect()
context.configure(connection=connection,
target_metadata=target_metadata,
compare_type=True,
process_revision_directives=process_revision_directives,
**current_app.extensions['migrate'].configure_args)
try:
with context.begin_transaction():
context.run_migrations()
finally:
connection.close()
さて、私の質問は次のとおりです。
Env.pyファイルを変更する際に何か問題がありましたか?
そうしなかったのにそれでもうまくいかない場合は、次の移行リビジョンを正確に手動で作成するにはどうすればよいですか?私の移行フォルダのリビジョンには以下のような名前があり、このようなものが含まれているためです
# revision identifiers, used by Alembic.
revision = '7e9f264b0f'
down_revision = '2e59d536f50'
私はただ1つをコピーして、名前を作ることができると思います..しかし、flask migrateによってピックアップされた次のものはそれを認識しますか?そうそう..それを処理する正しい方法は何ですかあまり気の利いたハッキングなしで?
更新:
予想通り、この回答は現在古くなっています。実際の修正については、 https://stackoverflow.com/a/52181159/428907 を参照してください。
元の回答:
Alembicは、デフォルトでリビジョンを自動生成するときに、列タイプの変更などを認識しません。これらのより詳細な変更を行う場合は、これらの変更を含めるように移行を手動で変更する必要があります
例:移行ファイル内
from alembic import op
import sqlalchemy as sa
def upgrade():
# ...
op.alter_column('downloads', 'size', existing_type=sa.Integer(), type_=sa.BigInteger())
def downgrade():
# ...
op.alter_column('downloads', 'size', existing_type=sa.BigInteger(), type_=sa.Integer())
操作の詳細については、 操作リファレンス を参照してください。
次に示すように、env.pyとalembic.iniを変更することで、タイプ変更の検出をオンにできます ここ
Migrateコンストラクターにcompare_type = Trueを追加する必要があります
from flask_migrate import Migrate
migrate = Migrate(compare_type=True)
app = Flask(__name__)
migrate.init_app(app)
デフォルトでは、Flask-migrateは、列のタイプが変更されたときに変更を追跡しません。これを達成するための多くの方法の1つは、
compare_type = True
env.pyの下。例えば-
context.configure(connection=connection,
target_metadata=target_metadata,
process_revision_directives=process_revision_directives,
compare_type=True,
**current_app.extensions['migrate'].configure_args)
_flask-migrate
_はほとんどの場合Column
の変更を検出しませんでした。 size
フィールドを削除すると、_flask-migrate
_が変更を検出します。次に実行します
_manager.py db migrate
_
次に、size
ファイルを追加します
size = db.Column(db.BigInteger, nullable=False)
そして移行します。
Flaskにcompare_type = trueを追加する自動化された方法のスクリプトを作成しました。自由に使用して、改善してください。
make dbinit
Sudo sed -i '75i\ compare_type=True,' env.py
make dbmigrate
make dbupgadre
乾杯、