Flask-SQLAlchemy: 没有这样的表

9
我会尽力帮助您进行翻译。以下是需要翻译的内容:

我正在尝试使用Flask-SQLAlchemy并遇到了一些问题。请看一下我正在使用的两个文件。当我运行gwg.py并转到/util/db/create-all时,它会输出一个错误没有这样的表:stories。我认为我做的一切都正确;有人可以指出我错过了什么或者出了什么问题吗?它确实创建了data.db文件,但该文件显示为0Kb。

gwg.py:

application = Flask(__name__)
db = SQLAlchemy(application)

import models

# Utility
util = Blueprint('util', __name__, url_prefix='/util')

@util.route('/db/create-all/')
def db_create_all():
    db.create_all()
    return 'Tables created'

application.register_blueprint(util)

application.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
application.debug = True
application.run()

models.py:

from gwg import application, db

class Story(db.Model):
    __tablename__ = 'stories'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(150))
    subscribed = db.Column(db.Boolean)

    def __init__(self, name):
        self.name = name
        self.subscribed = False

    def toggle_subscription(self):
        self.subscribed = False if self.subscribed else True

编辑

以下是似乎触发错误的函数,但不应该如此,因为我明确先转到 /util/db/create-all 然后重新加载/。即使在出现错误之后,我也会前往 /util/db/create-all,然后前往 /,但仍然会收到相同的错误提示。

@application.route('/')
def homepage():
    stories = models.Story.query.all()
    return render_template('index.html', stories=stories)

堆栈跟踪

sqlalchemy.exc.OperationalError
OperationalError: (OperationalError) no such table: stories u'SELECT stories.id AS stories_id, stories.name AS stories_name, stories.subscribed AS stories_subscribed \nFROM stories' ()

Traceback (most recent call last)
File "C:\Python27\lib\site-packages\flask\app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Python27\lib\site-packages\flask\app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Python27\lib\site-packages\flask\app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python27\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\kylee\Code\GWG\gwg.py", line 20, in homepage
stories = models.Story.query.all()
File "C:\Python27\lib\site-packages\sqlalchemy\orm\query.py", line 2104, in all
return list(self)
File "C:\Python27\lib\site-packages\sqlalchemy\orm\query.py", line 2216, in __iter__
return self._execute_and_instances(context)
File "C:\Python27\lib\site-packages\sqlalchemy\orm\query.py", line 2231, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 662, in execute
params)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 761, in _execute_clauseelement
compiled_sql, distilled_params
File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 874, in _execute_context
context)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1024, in _handle_dbapi_exception
exc_info
File "C:\Python27\lib\site-packages\sqlalchemy\util\compat.py", line 163, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 867, in _execute_context
context)
File "C:\Python27\lib\site-packages\sqlalchemy\engine\default.py", line 324, in do_execute
cursor.execute(statement, parameters)
OperationalError: (OperationalError) no such table: stories u'SELECT stories.id AS stories_id, stories.name AS stories_name, stories.subscribed AS stories_subscribed \nFROM stories' ()
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
Brought to you by DON'T PANIC, your friendly Werkzeug powered traceback interpreter.

请问您能否添加完整的错误堆栈跟踪信息? - Miguel Grinberg
已更新,包含堆栈跟踪。 - user2545155
我刚试着在sqlite3浏览器中打开它,但它说这不是一个sqlite3数据库。我知道不会有表,因为文件大小为0kb。但它是由SQLAlchemy创建的文件,所以我很困惑。 - user2545155
我有点困惑,/util/db/create-all 是出错了还是成功了(返回“Tables created”),但你的 SQLite 文件是空的? - Mark Hildreth
是的。我访问localhost/util/db/create-all,收到消息“表已创建”,此时会创建文件data.db,但该文件为空。当我返回localhost/时,就会出现堆栈跟踪错误,指出不存在任何表。我认为我的实现与Flask-SQLAlchemy在其文档中给出的示例非常接近。 - user2545155
1个回答

13

这里的问题在于Python导入系统中的一个陷阱。它可以简化为以下解释...

假设您有一个目录中的两个文件...

a.py:

print 'a.py is currently running as module {0}'.format(__name__)
import b
print 'a.py as module {0} is done'.format(__name__)

b.py:

print 'b.py is running in module {0}'.format(__name__)
import a
print 'b.py as module {0} is done'.format(__name__)

运行python a.py的结果如下...

a.py is currently running as module __main__
b.py is running in module b
a.py is currently running as module a
a.py as module a is done
b.py as module b is done
a.py as module __main__ is done

请注意,当运行 a.py 时,该模块会被称为 __main__

现在考虑你所拥有的代码。在其中,你的 a.py 脚本创建了你的 applicationdb 对象。但是,这些值并没有存储在名为 a 的模块中,而是存储在名为 __main__ 的模块中。因此,当 b.py 尝试导入 a 时,它不会导入你刚刚创建的那些值!相反,因为它找不到模块 a,它会再次运行 a.py 并将结果存储到模块 a 中。

你可以像我上面展示的那样使用 print 语句来帮助你了解整个过程,以便准确地查看发生了什么。解决方法是确保你只调用一次 a.py,当 b.py 导入 a 时,它将导入与 a.py 相同的值,而不是再次导入。

最简单的解决方法是创建一个专门用于运行应用程序的 Python 脚本。从 gwg.py 的末尾删除 application.run(),并添加以下脚本...

main.py:

from gwg import application
application.run()

然后使用python main.py运行。


这绝对有效!我知道它可能与循环导入有关,但不知道具体是怎么回事。谢谢! - user2545155

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接