Flask SQLAlchemy db.create_all() 不创建数据库

11 投票
1 回答
24117 浏览
提问于 2025-04-19 14:52

我搞不懂为什么我调用 db.create_all() 这个方法没有效果。

我有一个应用包,里面有以下的初始化代码:

from flask import Flask
from config import config
from flask.ext.sqlalchemy import SQLAlchemy

# create the database object
db = SQLAlchemy()

# this function is the application factory
def create_app(environment):
    app = Flask(__name__)
    app.config.from_object(config[environment])

    db.init_app(app)

    from bp_root import bp_root
    from bp_aws import bp_aws

    app.register_blueprint(bp_root, url_prefix='/')
    app.register_blueprint(bp_aws, url_prefix='/aws')

    return app

然后在这个应用包里还有一个 models.py 文件:

from datetime import datetime
from . import db

class MyTestClass(db.Model):
    __tablename__ = 'mytesttable'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), nullable=False, unique=True, index=True)
    username = db.Column(db.String(64), nullable=False, unique=True, index=True)
    is_admin = db.Column(db.Boolean)
    password_hash = db.Column(db.String(128))
    location = db.Column(db.String(64))
    member_since = db.Column(db.DateTime, default=datetime.utcnow)
    bio = db.Column(db.Text())

    def __init__(self, email, username):
        self.email = email
        self.username = username

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

app.config 里面包含了很多东西,其中有以下内容:

'SQLALCHEMY_DATABASE_URL': 'sqlite:////Users/xxxxx/projects/yyyyy/data-dev.sqlite'

接着,如果我打开交互式命令行,你可以看到对象都存在,而且调用 db.create_all() 看起来是有效的,但就是没有创建出数据库:

$ ./manage.py shell
>>> from app import db
>>> from app import models
>>> app
<Flask 'app'>
>>> db
<SQLAlchemy engine='sqlite://'>
>>> models
<module 'app.models' from '/Users/xxxxx/projects/yyyyy/app/models.py'>
>>> dir(models)
['MyTestClass', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'datetime', 'db']
>>> db.create_all()
>>> 

有没有人知道为什么数据库没有被创建呢?

1 个回答

12

这个设置应该是 SQLALCHEMY_DATABASE_URI,而不是 URL。你可以看到,当你运行这行代码时,数据库没有正确的 URI:

>>> db
<SQLAlchemy engine='sqlite://'>

这说明 Flask-SQLAlchemy 默认使用了一个内存中的 sqlite 数据库。只要更改这个设置,它就能正常工作了。

从 Flask-SQLAlchemy 3 开始,如果设置不对,它会直接报错,而不是使用默认值。

RuntimeError: Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set

撰写回答