Flask:由于KeyError,应用程序无法运行

时间:2018-07-19 07:12:44

标签: python python-3.x flask flask-sqlalchemy

我目前正在研究如何使用Flask开发Web应用程序,而我正在遵循this教程中进行操作的方法,直到引入Flask-SQLAchemy的概念,一切都进行得很好。

我的烧瓶应用程序的结构如下

├── bin
├── bookshelf
│   ├── admin
│   │   ├── controllers.py
│   │   ├── __init__.py
│   ├── data
│   │   ├── __init__.py
│   │   ├── models.py
│   ├── __init__.py
│   ├── main
│   │   ├── controllers.py
│   │   ├── __init__.py
│   ├── static
│   └── templates
├── config.py
├── data-dev.sqlite
├── docs
├── requirements.txt
├── run.py

我试图使用我自己设计的sqlite数据库(data-dev.sqlite),而不必经历SQLAchemy为我创建一个或以下的过程,它的结构是;使用sqlite中的.dump命令生成的

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE author (
id INTEGER NOT NULL PRIMARY KEY,
author_names VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE book (
id INTEGER NOT NULL PRIMARY KEY,
title VARCHAR(80) NOT NULL,
rating INT,
image VARCHAR(30),
author_id INTEGER NOT NULL,
FOREIGN KEY (author_id) REFERENCES author(id)
);
CREATE TABLE role (
id INTEGER NOT NULL PRIMARY KEY,
role_name VARCHAR(80) NOT NULL UNIQUE,
description VARCHAR(255)
);
CREATE TABLE user (
id INTEGER NOT NULL PRIMARY KEY,
email VARCHAR(75) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
active BOOLEAN NOT NULL DEFAULT 0,
role_id INTEGER NOT NULL,
FOREIGN KEY (role_id) REFERENCES role(id)
);
COMMIT;

当我在python run.py runserver -d中运行命令venv时产生的追溯是

Traceback (most recent call last):
  File "run.py", line 1, in <module>
    from bookshelf import create_app
  File "/home/mayatsa/environments/flask-test/bookshelf/__init__.py", line 2, in <module>
    from bookshelf.main.controllers import main
  File "/home/mayatsa/environments/flask-test/bookshelf/main/controllers.py", line 2, in <module>
    from bookshelf.data.models import Author, Book
  File "/home/mayatsa/environments/flask-test/bookshelf/data/models.py", line 6, in <module>
    class Book(db.Model):
  File "/home/mayatsa/environments/flask-test/bookshelf/data/models.py", line 8, in Book
    __table__ = db.Model.metadata.tables['book']
KeyError: 'book'

从上到下的追溯文件顺序及其内容如下

run.py

from bookshelf import create_app
from flask_script import Manager

app = create_app()
manager = Manager(app)

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

书架/ __ init __。py

from flask import Flask
from bookshelf.main.controllers import main
from bookshelf.admin.controllers import admin
from bookshelf.data.models import db

def create_app():
    app = Flask(__name__)
    app.config.from_object('config')

    with app.app_context():
        db.init_app(app)
        db.Model.metadata.reflect(db.engine)

    app.register_blueprint(main, url_prefix='/')
    app.register_blueprint(admin, url_prefix='/admin')

    return app

bookshelf / main / controllers.py

from flask import Blueprint, render_template, request
from bookshelf.data.models import Author, Book

main = Blueprint('main', __name__, template_folder='templates')

@main.route('/')
def index():
    return render_template('main/index.html')

@main.route('books/')
def display_books():
    return render_template('main/books.html')

bookshelf / data / models.py

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Book(db.Model):
    __table__ = db.Model.metadata.tables['book']
    def __repr__(self):
        return '<Book %r>' % (self.title)

class Author(db.Model):
    __table__ = db.Model.metadata.tables['author']
    def __repr__(self):
        return '<Author %r>' % (self.author_names)

class Role(db.Model):
    __table__ = db.Model.metadata.tables['role']
    def __repr__(self):
        return '<Role %r>' % (self.role_name)

class User(db.Model):
    __table__ = db.Model.metadata.tables['user']

    def __repr__(self):
        return '<User %r>' % (self.email)

其他 config.py

import os
basedir = os.path.abspath(os.path.dirname(__file__))

DEBUG = True
TESTING = False
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
    'sqlite:///' + os.path.join(basedir, 'data-dev.sqlite')
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = 'a9eec0e0-23b7-4788-9a92-318347b9a39f'

从上面提供的所有代码中,是什么导致我的应用程序产生此错误并使其停止运行? 谢谢

2 个答案:

答案 0 :(得分:0)

我不断探索,直到降落在this questionthis one上,他们为我扫清了雾气。

使用安装了sqlacodegenflask-sqlacodegen

pip install sqlacodegen
pip install flask-sqlacodegen

我现在要做的就是在我的Flask应用程序根目录中运行以下命令

sqlacodegen sqlite:///data-dev.sqlite --flask > models.py

生成了与我的数据库相对应的模型,然后在将bookshelf/data/models.py替换为刚生成的models.py之后。

然后最终更改了bookshelf/__init__.py create_app 函数,如下所示:

def create_app():
    app = Flask(__name__)
    app.config.from_object('config')

    db.init_app(app)

    app.register_blueprint(main, url_prefix='/')
    app.register_blueprint(admin, url_prefix='/admin')

    return app

现在一切似乎都正常了。

答案 1 :(得分:-1)

导入bookshelf.data.models时元数据还不存在,因为元数据仅在之后才反映在元数据中。

也许使用__tablename__代替__table__可能有所帮助?我对SQLAlchemy的复杂性不太了解。