当我将SQLALCHEMY_DATABASE_URI设置为Config中的路径时,为什么将其设置为“ sqlite:///:memory:”?

时间:2019-05-21 03:19:30

标签: flask-sqlalchemy

我正在按照Miguel Ginsberg大型教程第4章学习Flask。当我从Anaconda命令面板运行任何Flask命令时,出现一个错误,其中包括“未设置SQLALCHEMY_DATABASE_URI或SQLALCHEMY_BINDS。”结果在内存中创建了一个SQLite数据库。

但是我创建了一个Config对象,该对象设置SQLALCHEMY_DATABASE_URI,SECRET_KEY和SQLALCHEMY_TRACK_MODIFICATIONS,并分别测试了python,并且一切正常。

我已经尝试了所有我能想到的一切,包括分别测试代码段,在网络上搜索至少8个小时,以及浏览Ginsberg的帖子,但没有任何效果。格雷厄姆(29号帖子)的一个人似乎也遇到了同样的问题,但金斯伯格(Ginsberg)没有给出有用的答案。

这是我的应用初始化代码

__init__

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from config import Config

app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)

from app import routes, models

这是我的配置,单独运行时可以使用。

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


class Config(object):
    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'app.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

为完整起见,这是我的路线和模型

from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import LoginForm


@app.route('/')
@app.route('/index')
def index():
    user = {'username': 'Miguel'}
    posts = [
        {
            'author': {'username': 'John'},
            'body': 'Beautiful day in Portland!'
        },
        {
            'author': {'username': 'Susan'},
            'body': 'The Avengers movie was so cool!'
        }
    ]
    return render_template('index.html', title='Home', user=user, posts=posts)


@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        flash('Login requested for user {}, remember_me={}'.format(
            form.username.data, form.remember_me.data))
        return redirect(url_for('index'))
    return render_template('login.html',  title='Sign In', form=form)

from datetime import datetime
from app import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __repr__(self):
        return '<User {}>'.format(self.username)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    def __repr__(self):
        return '<Post {}>'.format(self.body)

应该发生的是,当我运行

这样的命令时
> flask db init

> flask db migrate -m "users table"

该命令应该成功完成,因为SQLALCHEMY_DATABASE_URI应该等于应用程序的路径,而SQLite数据库应该是app.db。

相反,我收到错误消息,指出未设置SQLALCHEMY_DATABASE_URI,因此SQLALCHEMY_DATABASE_URI已设置为“ sqlite:///:memory:”

我的应用程序需要一个持久数据库!为什么未设置SQLALCHEMY_DATABASE_URI和SQLALCHEMY_TRACK_MODIFICATIONS?

1 个答案:

答案 0 :(得分:0)

这个问题本身已经消失了,但是由于其他人可能会遇到这个问题,我决定描述一下我用来为他们节省一些挫败感的变通方法。我认为最初的问题可能是由于导入包/模块并将类/对象初始化到__init__方法中的顺序所致。

解决方法是注释掉原始config语句,然后直接在__init__中设置配置变量,包括SQLite数据库。

### app.config.from_object(Config)
app.config["SECRET_KEY"] = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get('DATABASE_URL') or \
     'sqlite:///' + 'C:\\...path...\\app.db'
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
...

可以通过使用

使该解决方法有所后退
import os
basedir = os.path.abspath(os.path.dirname(__file__))

...

SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
        'sqlite:///' + os.path.join(basedir, 'app.db')
...