Flask-migrate multiple models.py - flask

I've a question related to Flask-migrate.
I'm creating a set of web services with Flask. I've split each web service in his own package in a python application.
The application structure look like this:
MyApp
WS1
models.py
WS2
models.py
CommonPackage
models.py
How can I import all the modules and init the db? I've tried to import them all manually but is not working.
I know that it works if I import the "app" from WS1 or Ws2 separately, but I would like to do this in a single operation, is this possible?
Here you can find the code for Flask-migrate:
#!virtualenv/bin/python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from config import SQLALCHEMY_DATABASE_URI
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
from WS1.models import Class1, Class2, Class3 <--- This is not importing
from WS2.models import Class4, Class5, Class6 <--- This is not importing
if __name__=='__main__':
manager.run()
This is the modules where I initialize SQLAlchemy session:
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from config import SQLALCHEMY_DATABASE_URI
engine = create_engine(SQLALCHEMY_DATABASE_URI, convert_unicode = True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
All the models import this module and inherit from Base.
Thanks a lot,
Enrico

When you are defining a custom declarative base you're not really using Flask-SQLAlchemy anymore—and Flask-Migrate reads the models from Flask-SQLAlchemy's internal declarative base. (That is why you have to initialize Migrate with both app and db).
Flask has an answer to the import cycle problem: Most Flask extensions have an .init_app() method to defer initializing the extension where necessary.
In the module where you currently create Base by hand, just do db = SQLAlchemy() and then in your models import db and use db.Models as your declarative base instead of Base. In your app.py, do the following:
from dbpackagename import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db.init_app(app)

Related

Flask - How to load database with config from Flask config?

My folder structure is the following:
- app.py
app
- __init__.py
- database.py
in app.py I have:
from app import create_app
app = create_app()
my init.py looks something like:
from flask import Flask
from app.database import db_session, init_db
db = SQLAlchemy()
def create_app():
myapp = Flask(__name__, static_folder='static', static_url_path='/static', template_folder="templates")
myapp.config.from_object('config.Config')
db.init_app(myapp)
migrate.init_app(myapp, db)
# loading blueprints
from app.core_bp import core_bp
myapp.register_blueprint(core_bp, url_prefix='/', template_folder="templates")
return myapp
and database.py looks like this
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///rapporteur.db')
db_session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine))
That sqlite path is currently hardcoded to raporteur.db but it should be loaded from config, because I don't want it hardcoded, but unfortunately the flask app is not yet loaded. So how would I do this?
You can use flask-sqlalchemy and set the SQLALCHEMY_DATABASE_URI in the config file.
class Config:
SQLALCHEMY_DATABASE_URI = 'sqlite:///rapporteur.db'
then in your init.py
from youApp import Config
def create_app(config_class=Config)
app = Flask(__name__)
app.config.from_object(config_class)
db = SQLAlchemy()
db.init_app(app)
return app

Flask csrf: key is missing with Blueprint

Hello everyone I have this issue I am not able to correct:
KeyError: 'A secret key is required to use CSRF.'
I am now using Flask with Blueprint.
I am not using CSRF at all but I think the LoginForm is.
I structured my project with Blueprint.
Before that, everything was find.
Here is my init.py file:
from flask import Flask
from flask_login import LoginManager
from flask_bcrypt import Bcrypt
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask.config import Config
from flask_wtf.csrf import CSRFProtect
db = SQLAlchemy()
migrate = Migrate(db)
bcrypt = Bcrypt()
csrf = CSRFProtect()
login_manager = LoginManager()
login_manager.login_view = "login"
login_manager.login_message_category = "info"
from Flask import models
from Flask.models import User
admin = Admin(name='Admin')
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(Config)
admin.init_app(app)
db.init_app(app)
csrf.init_app(app)
login_manager.init_app(app)
migrate.init_app(app)
bcrypt.init_app(app)
db.init_app(app)
from Flask.users.routes import users
app.register_blueprint(users)
return app
This is my config.py file:
import os
class Config:
SECRET_KEY = "ef2006629e09b70e55a6fb95c4e3a538"
SQLALCHEMY_DATABASE_URI = "sqlite:///site.db"
# WTF_CSRF_SECRET_KEY= "bjk567nvhbvj63vg363vghvghv3768vgfbkijvr784"
# CSRF_ENABLED = True
Thank you for your help !
You should create a SECRET_KEY=<Your secret key here> property in your configuration. It must be a difficult string.
I found the problem
I was not calling properly my config.py file
In my init.py file I change the line:
from flask.config import Config
with the line:
from Flask.config import Config
Flask is the name of my file, which is different from flask.
I should have found another name

How do I import a database made with SQLAlchemy to Flask app?

new to web developing. I have three files. database_setup.py with my table classes. restaurant.py used to populate tables and script.py for flask app
database_setup.py
import os
import sys
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()
class Restaurant(Base):
__tablename__ = 'restaurant'
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.create_all(engine)
restaurant.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Restaurant, Base, MenuItem
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
restaurant = Restaurant(name= "Kasra")
session.add(restaurant)
session.commit()
script.py
from flask import Flask
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker,scoped_session
from database_setup import Base, Restaurant
app = Flask(__name__)
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = scoped_session(sessionmaker(bind=engine))
session = DBSession()
#app.route('/')
#app.route('/hello')
def HelloWorld():
restaurant = session.query(Restaurant).first()
return restaurant.name
if __name__ == "__main__":
app.run(debug=True)
What I want to do is import the database that was created in restarant.py to script.py. When I run the app it creates a new and empty database because I'm using "engine = "create_engine()" in script.py and I need to use it in order to bind with engine and use session.
The error I get when running app "AttributeError: 'NoneType' object has no attribute 'name'"
Here is what I do to operate with Flask and SQLAlchemy:
In a database.py file:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base
engine = create_engine(Config.SQLALCHEMY_DATABASE_URI)
session_factory = sessionmaker(bind=engine)
def init_db():
Base.metadata.create_all(bind=engine)
All model classes are located in a models.py file, and are also derived from the declarative base:
Base = declarative_base()
Then the start-up python script contains (key parts only):
app = Flask(__name__)
session = flask_scoped_session(session_factory, app)
if __name__ == "__main__":
database.init_db()
app.run()

Problems in importing modules in flask app

I am having lot of problem in importing modules.
The content in my files is above:
run.py:
from erp import app
if __name__ == '__main__':
app.run(debug=True)
all_blueprints.py:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from blueprint_finance.all_resources import api_finance
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"
db = SQLAlchemy(app)
ma = Marshmallow(app)
app.register_blueprint(api_finance)
erp/init.py
from .all_blueprints import app, db, ma
database1.py
from erp import app
class Author(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
I keep getting import errors, the current one is
Traceback (most recent call last):
File "/home/arsalan/python_practise/MY_WORK_FILES/React_works/React_Container_Mount/backend/run.py", line 25, in
from erp import app
File "/home/arsalan/python_practise/MY_WORK_FILES/React_works/React_Container_Mount/backend/erp/init.py", line 1, in
from .all_blueprints import app, db, ma
File "/home/arsalan/python_practise/MY_WORK_FILES/React_works/React_Container_Mount/backend/erp/all_blueprints.py", line 12, in
from blueprint_finance.all_resources import api_finance
ModuleNotFoundError: No module named 'blueprint_finance'
If anyone can point out the mistake's' that will be great favor because I am lost since yesterday. Thanks a lot!
I think the way you create your blueprints is not the right way (See this link for a detailed explanation).
If we refer to the way you have structured your code,
erp/
blueprint_finance ---> is your blueprint package
__init__.py ---> is where you create your blueprint
all_blueprints.py ---> is where you register your blueprint
let's start with the erp/blueprint_finance/__init__.py file:
from flask import Blueprint
bp = Blueprint('blueprint_finance', __name__)
from erp.blueprint_finance import all_resources
from erp.blueprint_finance.finances_resources import resource1
erp/all_blueprints.py
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"
db = SQLAlchemy(app)
ma = Marshmallow(app)
from erp.blueprint_finance import bp as blueprint_finance_bp
app.register_blueprint(blueprint_finance_bp)

Flask, SQLAlchemy, Data Tables - ImportError: cannot import name 'db' in Models.py

I'm trying to use Data Tables with Flask and SQLAchemy and I'm facing the
ImportError: cannot import name 'db'
in module Models.py
My project tree:
app
/common
__init__.py
models.py
toutes.py
/mod_tables
---
__init__
config.py
__init__.py
from flask import Flask, redirect, session
from app.mod_tables.models import TableBuilder
from app.config import Config
from flask_sqlalchemy import SQLAlchemy
#from flask_migrate import Migrate
app = Flask(__name__)
table_builder = TableBuilder()
app.config.from_object(Config)
db = SQLAlchemy(app)
db.init_app(app)
#migrate = Migrate(app, db)
from app.common.routes import main
from app.common import models
from app.mod_tables.controllers import tables
# Register the different blueprints
app.register_blueprint(main)
app.register_blueprint(tables)
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'spbData-V3560-FRANCO.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
\common.models.py
from app import db
class TipoPoste(db.Model):
tp_tipo = db.Column(db.String(35), primary_key=True)
tp_descricao = db.Column(db.String(255))
def __repr__(self):
return '<Tipo Poste {} - {}>'.format(self.tp_tipo,
self.tp_descricao)
Thos code gives me the following error:
flask.cli.NoAppException flask.cli.NoAppException: While importing
"app", an ImportError was raised:
Traceback (most recent call last): File
"c:\users\rfran.v3560-franco\appdata\local\programs\python\python36-32\lib\site-packages\flask\cli.py",
line 235, in locate_app
__import__(module_name) File "C:\Users\rfran.V3560-FRANCO\OneDrive\ArquivosLocais\gepoc\app\__init__.py",
line 2, in <module>
from app.mod_tables.models import TableBuilder File "C:\Users\rfran.V3560-FRANCO\OneDrive\ArquivosLocais\gepoc\app\mod_tables\models.py",
line 3, in <module>
from app.common.models import TipoPoste File "C:\Users\rfran.V3560-FRANCO\OneDrive\ArquivosLocais\gepoc\app\common\models.py",
line 1, in <module>
from app import db ImportError: cannot import name 'db'
Any hint? Thanks in advance.
Your error is caused by a circular import.
db is imported from app/init.py into the app/common/models.py module then the entire models.py module, including the db object, is imported into the app/init.py module. This is a circular import of the db object.
Instead, import the specific objects from the models.py file that you need:
init.py
...
from app.common.routes import main
from app.common.models import TipoPoste
from app.mod_tables.controllers import tables
...
That should fix it.
A good practice is not importing entire modules as you've done here. This could cause conflicts in some names that you may not be obvious at first. It'll save you lots of debugging time.
Try move db object into models.py. I omitted some unnecessary code.
__init__.py
...
from app.common.models import db
...
app = Flask(__name__)
db.init_app(app)
...
models.py
...
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
...