命令行执行.py文件通过flask-script初始化数据库提示ModuleNotFoundError: No module named 'XXX' 解决方法

项目中需要初始化数据库等操作,我用了flask-script的manage类来完成,所以按照标准的demo样式单独写了manage .py,来执行部署后的初始化工作,先看我的项目结构:
项目结构树

代码如下:

# -*- coding:utf-8 -*-
from flask import Flask
from flaskdemo.db import db
from flask_script import Manager, prompt_bool
from flaskdemo.config import SQLConfig

app = Flask(__name__)
manage = Manager(app)
app.config.from_object(SQLConfig)
db.init_app(app)


@manage.option('-d', '-drop', dest='drop', default='no')
def initdb(drop):
    """Initialize the database."""
    if drop == 'yes':
        if prompt_bool("Are you sure you want to lose all your data?"):
            db.drop_all()
            print('drop tables done.')
    db.create_all()
    print('Initialized database.')


if __name__ == '__main__':
    manage.run()

然后在Teminal中切换到项目目录后执行:

>>> cd flaskdemo
>>> python manage.py initdb

直接报错:

Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from flaskdemo.db import db
ModuleNotFoundError: No module named 'flaskdemo'

明明就有这个文件,可是死活就import失败,在pytharm上执行都是OK的,所以怀疑是目录问题,因为我项目主文件是main.py,所以path的设定及FLASK_APP等环境变量这些个问题我有点凌乱,比如总是无法设置成flask run直接执行程序,只能靠pytharm的run命令。囧。
自己不懂就问度娘吧,在网上找到两篇靠谱的文章:
https://www.cnblogs.com/dreamyu/p/7889959.html
https://blog.csdn.net/jianglianye21/article/details/78086768

问题和我一样,是cmd/shell直接运行.py文件时系统环境变量path中没有当前.py文件的目录,导致无法import所需要的模块,我们要做的就是在path环境变量中追加入文件所在的目录:

# -*- coding:utf-8 -*-
import sys
import os
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)

那么这段代码什么意思呢?如果熟悉os.path和sys.path的人一看就知道,不熟悉的还要普及下,比如我,orz…

os.path.abspath(path)

返回path规范化的绝对路径。

>>> os.path.abspath('test.csv') 
'C:\\Python25\\test.csv' 

os.path.dirname(path)

返回path的目录。其实就是os.path.split(path)的第一个元素。

>>> os.path.dirname('c:\\csv\test.csv') 
'c:\\csv' 

os.path.split(path)

将path分割成目录和文件名二元组返回。

>>> os.path.split('c:\\csv\\test.csv') 
('c:\\csv', 'test.csv')

sys.path.append(path)

将path加入系统环境变量path
sys.path是python的搜索模块的路径集,是一个list

['', 'C:\\WINDOWS\\system32\\python26.zip', 'C:\\Python26\\DLLs', 'C:\\Python26\ \lib', 'C:\\Python26\\lib\\plat-win', 'C:\\Python26\\lib\\lib-tk', 'C:\\Python26 ', 'C:\\Python26\\lib\\site-packages', 'C:\\Python26\\lib\\site-packages\\win32' , 'C:\\Python26\\lib\\site-packages\\win32\\lib', 'C:\\Python26\\lib\\site-packa ges\\Pythonwin']

append(path)其实就是相当于set path=%path%;path

所以以上代码其实就是将manage.py文件的目录添加到环境变量path里去,之前在IDE里面能跑是因为IDE设置了path,我们已经在默认的项目路径中,所以直接执行是没有问题的。但在cmd中执行程序,所在路径是python的搜索路径,如果涉及到import引用就会报类似ImportError: No module named xxx这样的错误,所以我们就需要手动添加当前目录到环境变量

对了,这段代码要放在import之前,所以最好直接放在manage.py文件开始。

欧了,走过的弯路+1

发布了25 篇原创文章 · 获赞 24 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/arnolan/article/details/84893088