Python &引用;导入错误:模块';xxxxxxxx和x27;没有属性';主要'&引用;将项目移植到Heroku时
我正在尝试将Python金字塔应用程序移植到Heroku 我必须承认,我不理解Python应用程序的文件结构,即使在阅读了这篇信息丰富的文章之后,它似乎包含了所有的答案: 我已经把一切都准备好了,这样我就可以把源代码更新推送到Heroku,并尝试进行构建。整个过程正在崩溃,因为明显缺少一个“主”属性。我不知道从哪里开始解决这个问题,因为我不知道“main”是什么,它的结构应该是什么,或者它应该驻留在什么文件中 我已经粘贴了我认为相关的内容,但请告诉我是否遗漏了一些有用的内容 我尝试按照这里的说明进行操作: 文件结构:Python &引用;导入错误:模块';xxxxxxxx和x27;没有属性';主要'&引用;将项目移植到Heroku时,python,heroku,pyramid,Python,Heroku,Pyramid,我正在尝试将Python金字塔应用程序移植到Heroku 我必须承认,我不理解Python应用程序的文件结构,即使在阅读了这篇信息丰富的文章之后,它似乎包含了所有的答案: 我已经把一切都准备好了,这样我就可以把源代码更新推送到Heroku,并尝试进行构建。整个过程正在崩溃,因为明显缺少一个“主”属性。我不知道从哪里开始解决这个问题,因为我不知道“main”是什么,它的结构应该是什么,或者它应该驻留在什么文件中 我已经粘贴了我认为相关的内容,但请告诉我是否遗漏了一些有用的内容 我尝试按照这里的说明
Procfile
run
runapp.py
wsgi.py
--->/corefinance/
----setup.py
----production.ini
------->/corefinance/
--------__init__.py
Heroku生成错误:
2016-10-10T04:44:45.496214+00:00 app[web.1]:
2016-10-10T04:44:45.496215+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.497067+00:00 app[web.1]: Searching for zope.deprecation==4.1.1
2016-10-10T04:44:45.497245+00:00 app[web.1]: Best match: zope.deprecation 4.1.1
2016-10-10T04:44:45.497356+00:00 app[web.1]: Adding zope.deprecation 4.1.1 to easy-install.pth file
2016-10-10T04:44:45.497742+00:00 app[web.1]:
2016-10-10T04:44:45.497745+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.498530+00:00 app[web.1]: Searching for Mako==1.0.0
2016-10-10T04:44:45.498709+00:00 app[web.1]: Best match: Mako 1.0.0
2016-10-10T04:44:45.498818+00:00 app[web.1]: Adding Mako 1.0.0 to easy-install.pth file
2016-10-10T04:44:45.503267+00:00 app[web.1]: Installing mako-render script to /app/.heroku/python/bin
2016-10-10T04:44:45.503522+00:00 app[web.1]:
2016-10-10T04:44:45.503524+00:00 app[web.1]: Using /app/.heroku/python/lib/python3.5/site-packages
2016-10-10T04:44:45.503725+00:00 app[web.1]: Finished processing dependencies for corefinance==0.0
2016-10-10T04:44:46.082134+00:00 app[web.1]: Traceback (most recent call last):
2016-10-10T04:44:46.082145+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2238, in resolve
2016-10-10T04:44:46.082291+00:00 app[web.1]: AttributeError: module 'corefinance' has no attribute 'main'
2016-10-10T04:44:46.082295+00:00 app[web.1]:
2016-10-10T04:44:46.082296+00:00 app[web.1]: During handling of the above exception, another exception occurred:
2016-10-10T04:44:46.082297+00:00 app[web.1]:
2016-10-10T04:44:46.082299+00:00 app[web.1]: Traceback (most recent call last):
2016-10-10T04:44:46.082334+00:00 app[web.1]: File "runapp.py", line 8, in <module>
2016-10-10T04:44:46.082511+00:00 app[web.1]: app = loadapp('config:production.ini', relative_to='./corefinance/')
2016-10-10T04:44:46.082519+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 247, in loadapp
2016-10-10T04:44:46.082666+00:00 app[web.1]: return loadobj(APP, uri, name=name, **kw)
2016-10-10T04:44:46.082668+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 271, in loadobj
2016-10-10T04:44:46.082894+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.082898+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 296, in loadcontext
2016-10-10T04:44:46.083142+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.083165+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 320, in _loadconfig
2016-10-10T04:44:46.083511+00:00 app[web.1]: return loader.get_context(object_type, name, global_conf)
2016-10-10T04:44:46.083514+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 454, in get_context
2016-10-10T04:44:46.083857+00:00 app[web.1]: section)
2016-10-10T04:44:46.083862+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 476, in _context_from_use
2016-10-10T04:44:46.084217+00:00 app[web.1]: object_type, name=use, global_conf=global_conf)
2016-10-10T04:44:46.084221+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 406, in get_context
2016-10-10T04:44:46.084536+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.084539+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 296, in loadcontext
2016-10-10T04:44:46.084822+00:00 app[web.1]: global_conf=global_conf)
2016-10-10T04:44:46.084826+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 328, in _loadegg
2016-10-10T04:44:46.085119+00:00 app[web.1]: return loader.get_context(object_type, name, global_conf)
2016-10-10T04:44:46.085123+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 620, in get_context
2016-10-10T04:44:46.085560+00:00 app[web.1]: object_type, name=name)
2016-10-10T04:44:46.085561+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/paste/deploy/loadwsgi.py", line 646, in find_egg_entry_point
2016-10-10T04:44:46.086013+00:00 app[web.1]: possible.append((entry.load(), protocol, entry.name))
2016-10-10T04:44:46.086015+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2230, in load
2016-10-10T04:44:46.086217+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.5/site-packages/setuptools-25.2.0-py3.5.egg/pkg_resources/__init__.py", line 2240, in resolve
2016-10-10T04:44:46.086408+00:00 app[web.1]: ImportError: module 'corefinance' has no attribute 'main'
runapp.py
import os
from paste.deploy import loadapp
from waitress import serve
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app = loadapp('config:production.ini', relative_to='./corefinance/')
serve(app, host='0.0.0.0', port=port)
./corefinance/setup.py
import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.txt')) as f:
README = f.read()
with open(os.path.join(here, 'CHANGES.txt')) as f:
CHANGES = f.read()
requires = [
'setuptools',
'markupsafe',
'pyramid',
'pyramid_chameleon',
'pyramid_debugtoolbar',
'pyramid_tm',
'SQLAlchemy',
'transaction',
'zope.sqlalchemy',
'waitress',
'docutils',
'pyramid_exclog',
'cryptacular',
'pycrypto',
'webtest',
]
setup(name='corefinance',
version='0.0',
description='corefinance',
long_description=README + '\n\n' + CHANGES,
classifiers=[
"Programming Language :: Python",
"Framework :: Pyramid",
"Topic :: Internet :: WWW/HTTP",
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
],
author='',
author_email='',
url='',
keywords='web wsgi bfg pylons pyramid',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
test_suite='corefinance',
install_requires=requires,
entry_points="""\
[paste.app_factory]
main = corefinance:main
[console_scripts]
initialize_corefinance_db = corefinance.scripts.initializedb:main
""",
)
./corefinance/corefinance/init.py
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from configparser import SafeConfigParser
import os
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.session import SignedCookieSessionFactory
from .security import groupfinder
from sqlalchemy import engine_from_config
from corefinance.models.meta import DBSession
from corefinance.models.utilities import RootFactory
from corefinance.models.meta import Base
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
parser = SafeConfigParser()
db_ini_file = settings['db_ini_file']
iniloc = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', db_ini_file))
read_list = parser.read(iniloc)
connstring = parser.get('postgres', 'connstring')
settings['sqlalchemy.url'] = connstring
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
session_factory = SignedCookieSessionFactory(
settings['session.secret']
)
authn_policy = AuthTktAuthenticationPolicy(
settings['session.secret'], callback=groupfinder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy()
config = Configurator(
settings=settings,
root_factory=RootFactory,
authentication_policy=authn_policy,
authorization_policy=authz_policy,
session_factory=session_factory
)
Base.metadata.bind = engine
config.include('pyramid_chameleon')
config.include(addroutes)
config.scan()
return config.make_wsgi_app()
我不认为这有什么不起作用的明确原因。不过,有几件事你可以改进 1) 大多数
setup.py
文件都希望从自己的目录中执行。当您运行python some_folder/setup.py develop
时,您要求的是一段糟糕的时间pip
为您解决了这个问题,您应该通过执行pip安装-e一些\u文件夹来切换到它
2) 确保与setup.py
相同的文件夹中没有init.py
,因为这可能会混淆依赖PYTHONPATH
发现代码的runapp.py
脚本,并且当前文件夹通常位于路径上,这意味着带有设置的文件夹.py
可以被视为一个包(并且在\uuuu init\uuuuuuu.py
中找不到main
)
要想弄明白这一点,最大的考验就是尝试在失败的环境中运行python
,然后尝试import corefinance
,看看你得到了什么。这应该会给你一些线索,说明它为什么不起作用。问题在于我的文件结构有一个额外的层次。正确的文件不在e根,你真的很接近了
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from configparser import SafeConfigParser
import os
from pyramid.authentication import AuthTktAuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.session import SignedCookieSessionFactory
from .security import groupfinder
from sqlalchemy import engine_from_config
from corefinance.models.meta import DBSession
from corefinance.models.utilities import RootFactory
from corefinance.models.meta import Base
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
parser = SafeConfigParser()
db_ini_file = settings['db_ini_file']
iniloc = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', db_ini_file))
read_list = parser.read(iniloc)
connstring = parser.get('postgres', 'connstring')
settings['sqlalchemy.url'] = connstring
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
session_factory = SignedCookieSessionFactory(
settings['session.secret']
)
authn_policy = AuthTktAuthenticationPolicy(
settings['session.secret'], callback=groupfinder, hashalg='sha512')
authz_policy = ACLAuthorizationPolicy()
config = Configurator(
settings=settings,
root_factory=RootFactory,
authentication_policy=authn_policy,
authorization_policy=authz_policy,
session_factory=session_factory
)
Base.metadata.bind = engine
config.include('pyramid_chameleon')
config.include(addroutes)
config.scan()
return config.make_wsgi_app()