Flask-Migrate遷移數(shù)據(jù)庫失敗的兩個Bug
1、找不到數(shù)據(jù)庫:Unknown database ‘***’
若還沒有創(chuàng)建數(shù)據(jù)庫,該遷移工具不會自動創(chuàng)建。你可以使用SQL命令手動創(chuàng)建一個數(shù)據(jù)庫:
create database <數(shù)據(jù)庫名稱>
2、遷移后沒有效果:No changes in schema detected.
我的情況長話短說,就是創(chuàng)建的數(shù)據(jù)模型類沒有注冊到程序實例app
,解決方案是使用工廠函數(shù)。細說如下:
在項目的主目錄下,有兩個文件如下所示。我在app.py
中創(chuàng)建了程序實例,在models.py
中定義了數(shù)據(jù)模型類。flask會自動嘗試在名為app.py
的文件中尋找程序實例,但不會管models.py
文件,而我沒有在app.py
中導入import models
,這樣它就只是一個孤立的文件,和不存在沒啥區(qū)別。
- app.py
- models.py
解決方案:
那我直接再
app.py
文件的頭部加一句import models
不就行了?
- /app.py
# import models
# 創(chuàng)建數(shù)據(jù)庫和程序實例
db = SQLAlchemy()
migrate = Migrate()
app = Flask(__name__)
# 注冊數(shù)據(jù)庫
db.init_app(app)
migrate.init_app(app, db)
- /models.py
from app import db
class UserModel(db.Model):
...
答案是不行。因為如果這樣的話,from app import db
會和import models
構成循環(huán)導入,導致程序報錯。
不過我觀察到,有的項目中創(chuàng)建程序實例采用了工廠函數(shù)形式,同時并沒有發(fā)生循環(huán)導入的問題。即把app
實例的創(chuàng)建過程代碼,從主流程轉移到一個函數(shù)中去,代碼如下所示:
工廠函數(shù):即返回值是一個可調(diào)用對象的函數(shù)。
# 創(chuàng)建數(shù)據(jù)庫實例
db = SQLAlchemy()
migrate = Migrate()
# 工廠函數(shù),返回實例對象
def create_app():
app = Flask(__name__)
...
db.init_app(app)
migrate.init_app(app, db)
# 導入數(shù)據(jù)模型
import models
return app
app = create_app()
循環(huán)導入的產(chǎn)生機制:
改用工廠函數(shù),是我看了別人的代碼后,胡亂之下做的一個嘗試,它確實成功解決了問題??墒?,我們不免心生疑惑:
沒道理啊,為什么工廠函數(shù)就可以,我直接導入就不可以呢?
這就不得不仔細思考:”循環(huán)導入“這一問題發(fā)生的具體條件是什么?只是簡單的”A中導入了B,而在B中也導入了A“嗎?此時不妨回想一下,Python是一門解釋性語言,代碼是一行一行地執(zhí)行的。
而在models.py
遇到導入語句from app import db
時,是怎樣的機制呢?此時會跳轉到app.py
,一行一行地執(zhí)行其中的代碼,直到找到對象db
為止,然后返回繼續(xù)執(zhí)行原文件models.py
中的代碼。
關于此機制我們不妨驗證一下,在同一目錄下創(chuàng)建兩個文件a.py
和b.py
如下。運行結果中輸出了"hello"
和"world"
,卻沒有輸出"python"
,說明在完成 f 函數(shù)的定義后,a.py
的執(zhí)行就停下來了,繼續(xù)執(zhí)行b.py
中的代碼。文章來源:http://www.zghlxwxcb.cn/news/detail-670066.html
- /a.py
print('hello')
def f():
print('world')
print('python')
- /b.py
from a import f
f()
-
python b.py
命令的執(zhí)行結果:
hello
world
所以,前面發(fā)生循環(huán)導入的核心問題,其實只是因為**app.py
中的import models
語句放在了創(chuàng)建數(shù)據(jù)庫實例的db = SQLAlchemy()
語句之前。** 我們只需要將import models
語句放到后面,完全不需要包裝一層工廠函數(shù),就可以解決這個問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-670066.html
到了這里,關于記Flask-Migrate遷移數(shù)據(jù)庫失敗的兩個Bug——詳解循環(huán)導入問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!