简体   繁体   中英

SQLAlchemy don't create tables if using Marshmallow

I'm trying to create a project using Flask , Flask-SQLAlchemy , flask-restplus and marshmallow (tried with flask-marshmallow too), but the integration of these tools does not work very well. Everytime I include some new lib, a new error occur.

I already give up to use migrations with Flask-SQLAlchemy because for some reason, this thing don't work. But now, the problem is with marshmallow .

I'm trying to make with modules and I think this is the part of the problem (all examples of Flask-SQLAlchmey, flask-restplus, flask-marshmallow, etc put everything in a single file)

This is my app.py :

from flask import Flask, Blueprint

import settings
from api import api
from database import init_database, reset_database

app = Flask(__name__)


def configure_app(flask_app):
    flask_app.config['SERVER_NAME'] = settings.SERVER_ADDRESS
    flask_app.secret_key = settings.SECRET_KEY


def initialize_app(flask_app):
    configure_app(flask_app)

    blueprint = Blueprint('api', __name__, url_prefix=settings.URL_PREFIX)
    api.init_app(blueprint)
    # api.add_namespace(auth_login_namespace)
    flask_app.register_blueprint(blueprint)

    init_database(flask_app)
    if settings.DEBUG:
        reset_database(flask_app)


def main():
    initialize_app(app)
    app.run(debug=settings.DEBUG)

if __name__ == '__main__':
    main()

api/__init__.py :

import settings

from flask_restplus import Api

api = Api(
    version='1.0',
    title='Test',
    description='Some description'
)


@api.errorhandler
def default_error_handler(e):
    message = 'An unhandled exception occurred.'

    if not settings.DEBUG:
        return {'message': message}, 500

database/__init__.py :

from flask_sqlalchemy import SQLAlchemy

import settings

db = SQLAlchemy()


def init_database(flask_app):
    flask_app.config['SQLALCHEMY_DATABASE_URI'] = settings.DATABASE_URI
    flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    global db # I really don't like this! :(
    db = SQLAlchemy(flask_app)


def reset_database(flask_app):
    from database.models import User
    db.drop_all()
    db.create_all()
    db.session.add(User(username='admin', email='abc@def.com', name='admin', password='123', admin=True)
    db.session.commit()

I have my app, with only one model until now:

database/models/User.py :

from marshmallow import Schema, fields
from sqlalchemy import func

from database import db


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, index=True)
    email = db.Column(db.String(120), unique=True, index=True)
    name = db.Column(db.String(200), nullable=False)
    password = db.Column(db.String(200), nullable=False)
    admin = db.Column(db.Boolean, nullable=False, default=False)
    created_on = db.Column(db.DateTime, nullable=False, server_default=func.now())


class UserSchema(Schema):
    id = fields.Int(dump_only=True)
    username = fields.Str()
    email = fields.Email()
    name = fields.Str()
    password = fields.Str()
    admin = fields.Bool()
    created_on = fields.DateTime()

now, if I use the following code (this code is called everytime my app start on debug mode, on function reset_database , in file database/__init__.py ):

db.drop_all()
db.create_all()
db.session.add(User(username='admin', email='abc@def.com', name='admin', password='123', admin=True)
db.session.commit()

the User table is not created, and the admin is not inserted on table, because the table don't exist ( db.create_all() don't create anything).

sqlite3.OperationalError: no such table: user .

For some reason, if I remove the class UserSchema (on database/models/User.py ), the db.create_all() function create the table).

Got working right now:

on database/__init__.py , altered the init_database function to:

def init_database(flask_app):
    flask_app.config['SQLALCHEMY_DATABASE_URI'] = settings.DATABASE_URI
    flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    db.init_app(flask_app)

and in database/reset_database.py :

def reset_database(flask_app):
    with flask_app.app_context():
        from database.models.user_module import User
        db.drop_all()
        db.create_all()
        db.session.add(User(username='admin', email='abc@def.com', name='admin', password='123', admin=True))
        db.session.commit()

The problems was the init_app , use the app_context , and I'm importing the wrong User module (tks Fian)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM