[英]Flask-admin cannot import name _class_resolver, under uWSGI and Nginx
我已經使用uWSGI和Nginx在AWS中托管了一個python Flask項目,最初一切正常,但是后來我決定實現Flask-admin模塊。 現在頁面向我顯示內部服務器錯誤消息。
我檢查了UWSGI日志並說:
Traceback (most recent call last):
File "/var/www/project/run.py", line 2, in <module>
from app import app
File "/var/www/project/app/__init__.py", line 22, in <module>
from app import views
File "/var/www/project/app/views.py", line 15, in <module>
from flask_admin.contrib.sqla import ModelView
File "/var/www/project/venv/local/lib/python2.7/site-packages/flask_admin/contrib/sqla/__init__.py", line 2, in <module>
from .view import ModelView
File "/var/www/project/venv/local/lib/python2.7/site-packages/flask_admin/contrib/sqla/view.py", line 17, in <module>
from flask_admin.contrib.sqla.tools import is_relationship
File "/var/www/project/venv/local/lib/python2.7/site-packages/flask_admin/contrib/sqla/tools.py", line 4, in <module>
from sqlalchemy.ext.declarative.clsregistry import _class_resolver
ImportError: cannot import name _class_resolver
Fri Nov 10 07:41:08 2017 - unable to load app 0 (mountpoint='project.domain.com|') (callable not found or import error)
Fri Nov 10 07:41:08 2017 - --- no python application found, check your startup logs for errors ---
我的app / views.py文件:
# -*- coding: utf-8 -*-
import os, time
import flask
from flask import render_template, request, jsonify, send_from_directory, send_file, session, redirect, g, url_for, make_response, session, request
from flask_sqlalchemy import SQLAlchemy
from models import RequestsLog
import requests
import json
from app import app, db, appname #Line edited
import flask_admin as admin
#from flask_admin import Admin, helpers, expose ------Line Erased
from flask_admin.contrib.sqla import ModelView
#from flask_admin.contrib import sqla ----------- Line Erased
class MyAdminIndexView(admin.AdminIndexView):
@admin.expose('/')
def index(self):
count = 56
return self.render('admin/index.html', count=count)
class CustomView(ModelView):
can_create = False
can_edit = False
can_delete = False # disable model deletion
can_export = True
export_columns = ['phone_number', 'doc_number', 'date', 'doc_type']
can_view_details = True
column_export_exclude_list = ['job_id', 'status']
list_template = 'list.html'
details_modal = True
page_size = 50
can_set_page_size = True
admin = admin.Admin(app, appname, template_mode='bootstrap3', index_view=MyAdminIndexView())
admin.add_view(CustomView(RequestsLog, db.session, menu_icon_type ='fa', menu_icon_value='fa-calendar'))
編輯:如果我評論此行一切正常,因為它應該:
from flask_admin.contrib.sqla import ModelView
谷歌搜索我注意到ImportError可能是由於冗余導入而引起的,但是我認為所有flask-admin導入都是必需的。
我認為問題不是由uWSGI引起的,但這是配置文件:
[uwsgi]
uid = www-data
gid = www-data
plugins=python
vhost=true
socket=/tmp/project.sock
chmod-socket = 666
chown-socket = www-data:www-data
enable-threads = true
procname-prefix = project_
chdir = /var/www/project
我再次創建了虛擬環境,但是一切都已完美安裝。
編輯:應該注意的是,當我直接執行run.py文件時,一切都按預期工作,即使使用flask-admin導入,問題也只存在於uWSGI下。
最后,我的項目托管在Ubuntu 14.04 Trusty AWS依賴項中。
編輯:
添加run.py文件:
#!venv/bin/python
from app import app
if __name__ == '__main__':
app.run(host='0.0.0.0', threaded=True, debug=True, port=5010)
編輯2:
添加__init__.py文件:
# -*- coding: utf-8 -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_socketio import SocketIO
#import flask_admin as admin
from flask_babel import Babel
#I've defined the next three lines to avoid encoding conflicts
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
app = Flask(__name__)
app.config.from_pyfile('../config.py')
appname = 'Project'
db = SQLAlchemy(app, session_options={'autoflush': False})
babel = Babel(app)
async_mode = None
socketio = SocketIO(app, async_mode=async_mode, ping_timeout=1800)
from app import views
venv/bin/pip freeze
輸出:
Babel==2.5.1
Flask==0.12.2
Flask-Admin==1.5.0
Flask-Babel==0.11.2
Flask-SQLAlchemy==2.3.2
Flask-SocketIO==2.9.2
Jinja2==2.9.6
MarkupSafe==1.0
SQLAlchemy==1.1.14
WTForms==2.1
Werkzeug==0.12.2
argparse==1.2.1
asn1crypto==0.22.0
certifi==2017.7.27.1
chardet==3.0.4
click==6.7
click-completion==0.2.1
colorama==0.3.9
crayons==0.1.2
elibom==1.2
gunicorn==19.7.1
idna==2.6
itsdangerous==0.24
psycopg2==2.7.3.1
py==1.4.34
pycycle==0.0.8
pytest==3.2.3
python-engineio==1.7.0
python-socketio==1.8.1
pytz==2017.3
requests==2.18.4
six==1.11.0
uWSGI==2.0.15
urllib3==1.22
wsgiref==0.1.2
Nginx配置文件:
server {
listen 80 ssl;
server_name project.domain.com;
listen 443 ssl;
ssl_certificate /etc/nginx/project.domain.com/fullchain.pem;
ssl_certificate_key /etc/nginx/project.domain.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM !RC4";
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
location /static/ {
autoindex on;
alias /var/www/project/app/static/;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/tmp/project.sock;
uwsgi_read_timeout 300;
uwsgi_param UWSGI_PYHOME /var/www/project/venv;
uwsgi_param UWSGI_CHDIR /var/www/project;
uwsgi_param UWSGI_MODULE run;
uwsgi_param UWSGI_CALLABLE app;
}
error_page 404 /404.html;
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:5010/socket.io;
}
}
非常感謝你的幫助。
我將從立即發生的錯誤開始,然后解決其運行方式可能與uWSGI不同的原因。
這里有一些快速而松散的導入,這在您構建某些東西或添加功能時很常見。 一個好的開始是將其削減以減少冗余並清理它。 即使您沒有在途中解決問題,每次刪除都會使其余的導入更容易考慮。
除了注釋中建議的Luis更改之外,您還可以組合以下兩行,這些行使用不同的約定從同一位置導入:
從flask_admin以管理員身份導入flask_admin導入Admin,助手,公開
您可以只導入flask_admin本身:
import flask_admin
...
class MyAdminIndexView(flask_admin.AdminIndexView):
@flask_admin.expose('/')
...
admin = flask_admin.Admin...
或者,您可以將AdminIndexView
添加到顯式導入列表中:
from flask_admin import Admin, AdminIndexView, helpers, expose
我遇到的大多數Flask導入錯誤都來自嘗試從尚未正確初始化的應用程序中導入另一個對象(通常是由於循環導入),所以我猜想它潛伏在這三行代碼中:
from app import app
...
from models import RequestsLog
...
from app import db, appname
原因可能會突如其來,但有時循環會深入幾個模塊。 如果沒有,那么下一步是通過諸如Pylint之類的linter運行您的項目。 如果您已經在運行Pylint,則可能需要仔細檢查您的設置,並確保啟用了與導入相關的規則! 如果尚未使用它,則可以從命令行手動運行它,也可以通過編輯器插件使用它,該插件可以在工作時通過它運行代碼(如果您還沒有使用它,可能會遇到很多問題linting-但我只專注於與導入/模塊相關的代碼)。
您也許還可以使用更集中的工具pycycle等更快地將其發布 ,盡管我尚未親自嘗試。
有時,您可以通過精心設計或稍加重構來避免Flask中的循環導入問題,但是隨着應用程序復雜性的增加,新功能很可能會導致您進行循環導入。 如果您確定了問題但找不到明顯的解決方法,則下一步通常是采用Flask 應用程序工廠模式 。 這種模式不是魔術,您仍然可以將自己畫在導入問題的角落,但是它確實會使它們更容易重構。
就目前而言,我認為這是當您從命令行以及從uWSGI后面通過python運行時看到不同行為的兩個最可能的原因。 這只是一般列表,因為更具體的答案取決於您包含的文件之外的其他內容。 uWSGI和nginx都具有相當復雜的配置選項數組,而且我從這里飛來飛去,所以我可能並不完全准確... :)
該應用程序是有條件設置的,可能使用環境變量或諸如if __name__ == '__main__':
,因此在兩種情況下您不會運行完全相同的代碼。
uWSGI沒有使用相同的可調用/模塊。 在配置文件和命令行之間,我記得有幾種方法可以告訴uWSGI加載哪個python文件,以及應用程序的python對象的名稱是什么,但是我不記得能夠從nginx做到這一點。 。 我看不到任何這些在你的配置文件中指定,但你包括日志片斷暗示而uWSGI正在試圖尋找一個可調用(通常發生在導入異常app
或application
中) run.py
。 您是否正在通過CLI運行相同的代碼?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.