【问题标题】:using Flask-Migrate together with Flask-Security将 Flask-Migrate 与 Flask-Security 一起使用
【发布时间】:2014-08-16 03:34:24
【问题描述】:

我正在尝试让一个基本的 Flask-Security 应用程序与 Flask-Migrate 一起使用。我有两个主要的 py 文件:app.py 和 db_migrate.py

app.py:

from flask import Flask, render_template, request, session
from flask.ext.babel import Babel
from flask.ext.mail import Mail
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin    
import os
basedir = os.path.abspath(os.path.dirname(__file__)) #should be __ file __ with no spaces

# Create app
app = Flask(__name__)
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'super-secret'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'app.db')
app.config['DEFAULT_MAIL_SENDER'] = 'info@site.com'
app.config['SECURITY_REGISTERABLE'] = True
app.config['SECURITY_CONFIRMABLE'] = True
app.config['SECURITY_RECOVERABLE'] = True
app.config.from_object('config.email')

# Setup mail extension
mail = Mail(app)

# Setup babel
babel = Babel(app)

@babel.localeselector
def get_locale():
    override = request.args.get('lang')

    if override:
        session['lang'] = override

    rv = session.get('lang', 'en')
    return rv

# Create database connection object
db = SQLAlchemy(app)

# Setup Flask-Security
from db_manager import User, Role #THIS IS PROBABLY WRONG!

user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

#db.create_all()

# Views
@app.route('/')
def home():
    return render_template('index.html')

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

db_migrate.py:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security, SQLAlchemyUserDatastore, UserMixin, RoleMixin

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

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'app.db')

db = SQLAlchemy(app)
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

# Define models
roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    favcolor = db.Column(db.String(255))
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

    def __str__(self):
        return '<User id=%s email=%s>' % (self.id, self.email)

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

我已经运行了迁移工具来初始化和迁移数据库一次,创建一个新的数据库,它工作了:

python db_manager.py db init
python db_manager.py db migrate

我尝试运行 app.py。它在 localhost 上正常运行,但是当我尝试登录用户时,我收到以下 OperationalError:

OperationalError: (OperationalError) no such table: user u'SELECT user.id AS user_id, user.email AS user_email, user.password AS user_password, user.active AS user_active, user.confirmed_at AS user_confirmed_at, user.favcolor AS user_favcolor \nFROM user \nWHERE lower(user.email) LIKE lower(?)\n LIMIT ?抵消 ?' (u'xxx@xxx.com', 1, 0)

基本上,我怀疑我是否正确创建了user_datastoresecurity,因为我可能不应该以这种方式导入UserRole——但我不确定如何访问正确的。

编辑:

感谢建议,我添加了最后一条命令:

python db_manager.py db ugrade

但是,现在当我尝试通过电子邮件确认用户注册时出现此错误:

(InvalidRequestError: Object '' is already attached to session '1' (this is '3')

【问题讨论】:

    标签: python flask flask-sqlalchemy flask-security flask-migrate


    【解决方案1】:

    Flask-Migrate/Alembic 的工作流程如下:

    1. db init

      您在创建迁移存储库时执行一次,以后再也不会这样做了。

    2. db migrate

      您运行它来生成一个迁移脚本。该命令的输出会告诉您迁移脚本的创建位置,并显示其中包含的内容的摘要。您的数据库在此阶段尚未修改。

    3. 查看迁移脚本

      这是非常重要的。自动迁移并不完美,您必须查看生成的脚本并进行必要的更正。

    4. db upgrade

      这会将迁移应用到您的数据库,有效地进行必要的架构更改。

    5. 您现在可以使用您的数据库了。当您对模型进行更多更改时,请返回第 2 步并重复该循环。

    根据您的描述,您可能错过了第 4 步,upgrade 电话。

    附带说明,您的两个脚本之间有一些重复,您应该尝试合并它们。看看人们如何构建跨多个模块或包的 Flask 应用程序。

    【讨论】:

    • 谢谢!我也采纳了您的建议,因为代码正在创建 2 个数据库连接。
    猜你喜欢
    • 1970-01-01
    • 2016-08-10
    • 2023-03-03
    • 2016-04-22
    • 2019-07-13
    • 2013-06-19
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    相关资源
    最近更新 更多