将Flask models.py迁移到MySQL

时间:2015-08-07 19:29:53

标签: python mysql database sqlite flask

我是新人。忍受我。

我正在开发一个使用SQLAlchemy作为ORM的Flask应用程序,直到今天我一直在使用SQLite以方便使用。我现在正在将应用程序放在Digital Ocean上,并希望使用MySQL而不是SQLite。

我在Digital Ocean上的ubuntu VPS上安装了MySQL,看起来配置正确。但是,显然我必须创建数据库表,所以我可以保存数据。

问题:我有没有办法迁移models.py,所以数据库表是根据我在models.py中编写的内容创建的,或者是否必须创建所有数据库表我自己在MySQL手动?

您可以在此处查看应用程序:http://workflowforum.dk/我已经做了一个小测试,看看这里是否有数据库连接:http://workflowforum.dk/testdb

Models.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 datetime import datetime, date
from hashlib import md5
from bcrypt import hashpw, gensalt

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password@localhost/database'
db = SQLAlchemy(app)

migrate = Migrate(app, db)

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

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(80))
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(80))
    password = db.Column(db.String(80), unique=False)
    admin = db.Column(db.Boolean(), default=False)
    join_date = db.Column(db.DateTime)
    last_seen = db.Column(db.DateTime)
    topics = db.relationship('Topic')
    posts = db.relationship('Post')
    picture = db.Column(db.Boolean(), default=False)
    title = db.Column(db.String(80))
    company = db.Column(db.String(80))
    summary = db.Column(db.String(80))

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(180), unique=False)
    topics = db.relationship('Topic', backref="category")

class Topic(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    slug = db.Column(db.String(255), unique=True)
    title = db.Column(db.String(80), unique=False)
    description = db.Column(db.Text, unique=False)
    pub_date = db.Column(db.DateTime)
    last_update = db.Column(db.DateTime)
    user_id = db.Column(db.String(80), db.ForeignKey('user.id'))
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    views = db.Column(db.Integer, default=0)
    locked = db.Column(db.Boolean(), default=False)
    pinned = db.Column(db.Boolean(), default=False)
    user = db.relationship('User')
    posts = db.relationship('Post')

Views.py(仅限数据库测试):

@app.route('/testdb')
    def testdb():
    if db.session.query("1").from_statement("SELECT 1").all():
        return 'It works.'
    else:
        return 'Something is broken.'
卢卡斯评论后

更新

尝试db.create_all()时,我得到了这个回溯:

sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1005, "Can't create table 'pwforum.topic' (errno: 150)") [SQL: u'\nCREATE TABLE topic (\n\tid INTEGER NOT NULL AUTO_INCREMENT, \n\tslug VARCHAR(255), \n\ttitle VARCHAR(80), \n\tdescription TEXT, \n\tpub_date DATETIME, \n\tlast_update DATETIME, \n\tuser_id VARCHAR(80), \n\tcategory_id INTEGER, \n\tviews INTEGER, \n\tlocked BOOL, \n\tpinned BOOL, \n\tPRIMARY KEY (id), \n\tUNIQUE (slug), \n\tFOREIGN KEY(user_id) REFERENCES user (id), \n\tFOREIGN KEY(category_id) REFERENCES category (id), \n\tCHECK (locked IN (0, 1)), \n\tCHECK (pinned IN (0, 1))\n)\n\n']

1 个答案:

答案 0 :(得分:1)

评论中的db.create_all建议通常是您在不使用迁移框架时所执行的操作。但看起来您在这里使用Flask-Migrate作为数据库迁移框架。执行create_all的问题是您的迁移脚本被跳过,因此您需要将sqlite模型转换为MySQL所需的任何修复都不会反映在迁移脚本中。

我的建议是你创建一个空的MySQL数据库,在你的Flask应用程序中配置它,然后只需调用:

就可以生成MySQL表。
$ ./manage.py db upgrade

执行此操作时,Flask-Migrate将逐个按顺序开始运行迁移脚本。

如果您遇到故障,可能是因为您的某些迁移脚本的更改与sqlite兼容,但与MySQL不兼容。您将需要在迁移脚本中修复所有这些问题,直到您完全运行所有这些问题,此时您将拥有一个完整的MySQL数据库以在您的应用程序中使用。