나는 영약 SQLAlchemy도, 증류기과 래퍼 플라스크에 (플라스크-SQLAlchemy의와 플라스 크 - 마이그레이션)와 프로젝트에서 일하고 있어요. 나는 네 마이그레이션이 : 나는 새로운 깨끗한 데이터베이스를 시작하고 내가 오류를 얻을 마이그레이션을 실행하려고Flask-Migrate가 2 단계 마이그레이션을 수행하는 이유는 무엇입니까?
1c5f54d4aa34 -> 4250dfa822a4 (head), Feed: Countries
312c1d408043 -> 1c5f54d4aa34, Feed: Continents
41984a51dbb2 -> 312c1d408043, Basic Structure
<base> -> 41984a51dbb2, Init Alembic
:
[email protected]:/vagrant$ python manage.py db upgrade
...
sqlalchemy.exc.ProgrammingError: (ProgrammingError) relation "continent" does not exist
...
내가 플라스크-마이그레이션은 모든 마이그레이션을 실행하도록 요구하는 경우에 있지만, 마지막으로 작동합니다. 그 후 나는 다시 업그레이드 명령을 실행하면 작동 - 즉, 완전히 코드에서 하나의 변화없이 내 데이터베이스를 업그레이드 :
[email protected]:/vagrant$ python manage.py db upgrade 312c1d408043
INFO [alembic.migration] Context impl PostgresqlImpl.
INFO [alembic.migration] Will assume transactional DDL.
INFO [alembic.migration] Running upgrade -> 41984a51dbb2, Init Alembic
INFO [alembic.migration] Running upgrade 41984a51dbb2 -> 312c1d408043, Basic Structure
[email protected]:/vagrant$ python manage.py db upgrade
INFO [alembic.migration] Context impl PostgresqlImpl.
INFO [alembic.migration] Will assume transactional DDL.
INFO [alembic.migration] Running upgrade 312c1d408043 -> 1c5f54d4aa34, Feed: Continents
INFO [alembic.migration] Running upgrade 1c5f54d4aa34 -> 4250dfa822a4, Feed: Countries
TL; DR
마지막으로 마이그레이션 (피드 : 국가)는 이전 피드 (Feed : Continents)가 제공 한 테이블에서 쿼리를 실행합니다. 대륙 테이블을 만들고 먹이면 스크립트가 작동해야합니다. 그러나 그렇지 않습니다. 다른 명령으로 다시 시작하려면 그 사이에 마이그레이션 프로세스를 중지해야하는 이유는 무엇입니까? 나는 정말로 이것을 얻지 못한다. Alembic이 일련의 이주 후에 실행하는 명령인가? 어떤 아이디어?
내 모델로 정의됩니다 이런 경우에
은 다음과 같습니다
class Country(db.Model):
__tablename__ = 'country'
id = db.Column(db.Integer, primary_key=True)
alpha2 = db.Column(db.String(2), index=True, unique=True)
title = db.Column(db.String(140))
continent_id = db.Column(db.Integer, db.ForeignKey('continent.id'))
continent = db.relationship('Continent', backref='countries')
def __repr__(self):
return '<Country #{}: {}>'.format(self.id, self.title)
class Continent(db.Model):
__tablename__ = 'continent'
id = db.Column(db.Integer, primary_key=True)
alpha2 = db.Column(db.String(2), index=True, unique=True)
title = db.Column(db.String(140))
def __repr__(self):
return '<Continent #{}: {}>'.format(self.id, self.title)
많은 감사,
UPDATE 1 : 마지막 두 마이그레이션의 업그레이드 방법을
@Miguel이 의견에서 묻는대로, 여기에 업그레이드가 있습니다. 마지막 두 마이그레이션 ethods :
피드 : 대륙
def upgrade():
csv_path = app.config['BASEDIR'].child('migrations', 'csv', 'en')
csv_file = csv_path.child('continents.csv')
with open(csv_file) as file_handler:
csv = list(reader(file_handler))
csv.pop(0)
data = [{'alpha2': c[0].lower(), 'title': c[1]} for c in csv]
op.bulk_insert(Continent.__table__, data)
피드 :
def upgrade():
# load countries iso3166.csv and build a dictionary
csv_path = app.config['BASEDIR'].child('migrations', 'csv', 'en')
csv_file = csv_path.child('iso3166.csv')
countries = dict()
with open(csv_file) as file_handler:
csv = list(reader(file_handler))
for c in csv:
countries[c[0]] = c[1]
# load countries-continents from country_continent.csv
csv_file = csv_path.child('country_continent.csv')
with open(csv_file) as file_handler:
csv = list(reader(file_handler))
country_continent = [{'country': c[0], 'continent': c[1]} for c in csv]
# loop
data = list()
for item in country_continent:
# get continent id
continent_guess = item['continent'].lower()
continent = Continent.query.filter_by(alpha2=continent_guess).first()
# include country
if continent is not None:
country_name = countries.get(item['country'], False)
if country_name:
data.append({'alpha2': item['country'].lower(),
'title': country_name,
'continent_id': continent.id})
csv로 I (마지막 마이그레이션에 공급 된 테이블에 따라 다름) 나라 기본적으로이 패턴을 따르고 있습니다 :
con tinents.csv
...
AS, "Asia"
EU, "Europe"
NA, "North America"
...
iso3166.csv
...
CL,"Chile"
CM,"Cameroon"
CN,"China"
...
_country_continent.csv_
...
US,NA
UY,SA
UZ,AS
...
그래서 피드 : 대륙 대륙 테이블을 공급하고, 피드 : 국가 국가 표를 먹인다. 그러나 그것은 대륙 테이블을 쿼리하여 대륙과의 적절한 연결 고리를 만들어야합니다.
UPDATE 2 : 레딧의 일부 사람은 이미 설명과
내가 the same question on Reddit 물었다 해결 방법을 제공하고, themathemagician는 말했다 : 레딧에 @themathemagician에 의해 표시된 바와 같이
I've run into this before, and the issue is that the migrations don't execute individually, but instead alembic batches all of them (or all of them that need to be run) and then executes the SQL. This means that by the time the last migration is trying to run, the tables don't actually exist yet so you can't actually make queries. Doing
from alembic import op def upgrade(): #migration stuff op.execute('COMMIT') #run queries
This isn't the most elegant solution (and that was for Postgres, the command may be different for other dbs), but it worked for me. Also, this isn't actually an issue with Flask-Migrate as much as an issue with alembic, so if you want to Google for more info, search for alembic. Flask-Migrate is just a wrapper around alembic that works with Flask-Script easily.
마지막 두 번의 마이그레이션 중'upgrade()'메소드를 추가 할 수 있습니까? – Miguel
@Miguel, 감사합니다. 방금 게시물을 편집하고 메소드를 추가했습니다. BTW, [다른 곳] (https://github.com/cuducos/whiskyton#thanks) 나는 당신에게 "고맙다"고 말했지만 어쩌면 당신은 그것을 보지 못했을 것입니다 - 그래서, 다시 한 번 더 공유하겠습니다 ... – cuducos