перенос базы данных в колбе - sqlalchemy - PullRequest
0 голосов
/ 16 мая 2018

flask-restplus и sqlalchemy для разработки моего бэкэнда. Я использую библиотеку flask-migrate, чтобы я мог настраивать таблицы базы данных при наличии таких требований.

Вот моя структура каталогов

-mainfolder/
     -app/
         -v1/
           -app.py
           -apis/
              -__init__.py
              -some folders.
               .
               .
               .
           -database/
              -__init__.py
              -models.py
           -config/
               -__init__.py
               -detect_config_file.py
            -

     -wsgi.py

Код в моем app.py равен

import logging.config
import json
import os
import sys
from flask import Flask, Blueprint
from flask_restplus import Api
from flask_jwt_extended import JWTManager
from flask_cors import CORS
from database import *
from config.detect_config_file import config

app = Flask(__name__)
cors = CORS(app)
api = Api(version='1.0', title='Plug-n-Play APIs',
      description='Demostration of APIs behind plug-n-play dashboard')
logging_conf_path = 
 os.path.normpath(os.path.join(os.path.dirname(__file__), '../../logging.conf'))
 logging.config.fileConfig(logging_conf_path)
 log = logging.getLogger(__name__)

def configure_app(flask_app):

     flask_app.config['JWT_SECRET_KEY'] = config['JWT_SECRET_KEY']
     flask_app.config['JWT_BLACKLIST_ENABLED'] = config['JWT_BLACKLIST_ENABLED']
     flask_app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = config['JWT_BLACKLIST_TOKEN_CHECKS']
     flask_app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://'+ config['DB_USERNAME'] + ':' + config['DB_PASSWORD']+'@'+ config['DB_HOST'] + '/' + config['DB_NAME']
     flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = config['DB_TRACK_MODIFICATIONS']


def initialize_app(flask_app):
   configure_app(flask_app)

    blueprint = Blueprint('api', __name__, url_prefix='/api/v1')
    api.init_app(blueprint)

    flask_app.register_blueprint(blueprint)

    db.init_app(flask_app)

    with flask_app.app_context():
      initDB()

    jwt = JWTManager(flask_app)


def main():
  initialize_app(app)
  log.info('>>>>> Starting development server <<<<<')
  app.run(debug=config['APP_DEBUG'], host="0.0.0.0")


if __name__ == "__main__":
  main()

models.py Файл в папке базы данных:

from database import db
#importing from __init__.py of database folder

from sqlalchemy.types import JSON
from sqlalchemy_utils.types.choice import ChoiceType
from config.detect_config_file import config
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app
#importing the flask app from app.py 

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

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

class UserModel(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(120), unique = True, nullable = False)

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

файл __ init __. Py в папке базы данных -

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


def initDB():
    from database.models import *
    db.create_all()

Мой мыслительный процесс заключается в том, что когда я запускаю app.py, он создает таблицы в моей базе данных (я уже создал базу данных в mysql), сегмент кода в app.py

with flask_app.app_context():
   initDB()

когда схема изменится, тогда в этом случае я буду выполнять эти команды, чтобы обновить мои базы данных без необходимости удалять и снова создавать базу данных.

$python models.py db init
$python models.py db migrate
$python models.py db upgrade

Но это не работает. Я получаю ошибку циклической зависимости, когда пытаюсь импортировать приложение из приложения в models.py

Пожалуйста, посмотрите на мой код и скажите мне, правильный ли мой подход или есть лучший способ сделать это. Моя главная цель - выполнить миграцию базы данных так же, как в django, чтобы я мог легко изменить схему базы данных.

1 Ответ

0 голосов
/ 09 июля 2018

Я бы предложил создать экземпляр app / db в app / init.py, чтобы app / db можно было импортировать из одного места.После того, как вы создадите экземпляр вашего менеджера, импортируйте его в run.py, который находится вне каталога приложения, и переключите его между app.run () / manager.run ()

model.py

from app import db
class UserModel(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer, primary_key = True)
    username = db.Column(db.String(120), unique = True, nullable = False)

project / app / init .py

def create_app():
    app = Flask(__name__)
    return app

app = create_app()
# import this db to your model.
db = SQLAlchemy(app)
manager = Manager(app)
manager.add_command('db', MigrateCommand)

project / run.py

# Placed from app import manager right above main block.
from app import manager

if __name__ == '__main__':
    # switch between run/manager based on your need.
    #manager.run() # for DB migration
    app.run(threaded=True, debug=True)
...