I am trying to initialise my db, and everytime i run the flask db init command, I get that error.
I am unsure why, my FLASK_APP and FLASK_ENV are set correctly.
I have been reorganising the project structure and file names to abide more with the flask guidelines in the moments before this.
run.py
from app import app
app.run(debug=True)
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = True
init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import views, models
db_create.py
from config import SQLALCHEMY_DATABASE_URI
from app import db
import os.path
db.create_all()
models.py
from app import db
class Property(db.Model):
id = db.Column(db.Integer, primary_key=True)
address = db.Column(db.String(500), index=True, unique=True)
start_date = db.Column(db.DateTime)
duration = db.Column(db.Integer)
rent = db.Column(db.Float)
views.py
from app import app
from flask import render_template
#app.route('/')
def index():
return render_template('index.html')
Error:
$ flask db init
Usage: flask db init [OPTIONS]
Error: Could not import "app.run".
edit: Folder structure so you can understand better:
config.py
run.py
app/
__init__.py
db_create.py
models.py
views.py
static/
templates/
index.html
layout.html
adding again: The issue is not running my code, it is when I am trying to initialise my db using flask db init
I get the error in my terminal when trying to run this, hoping someone can help me figure out why and then fix it, thanks for reading :)
Please make sure that your working directory is not inside your flask app app/.
flask_app/
config.py
run.py
app/
__init__.py
db_create.py
models.py
views.py
static/
templates/
index.html
layout.html
In this case, your working directory should be flask_app/.
you need to check the flask app variable again with echo $FLASK_APP.
In Miguel's Tutorial, FLASK_APP is set in .flaskenv, however you need to make sure that FLASK_APP is really set to your starter file. I had the default value set to run.py, which impaired starting up the migration repo. so set it with export FLASK_APP=<your-app-starter-file>.py.
Related
I am learning flask. I have a directory structure that looks something like this.
project
- controllers
-- auth.py
-- main.py
- db
-- setup.py
- models
-- models.py
- templates
-- base.html
-- index.html
-- login.html
-- signup.html
-- 404.html
-__init__.py
The file init.py looks like this
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:#localhost/mission_to_mars'
db.init_app(app)
# blueprint for auth routes in our app
from .controllers.auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .controllers.main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
I'm trying to import the db variable and create_app() function in controllers/auth.py, controllers/main.py, models/models.py, db/setup.py
I have tried the below syntaxes
from .. import db, create_app
which gives the error:
ImportError: attempted relative import with no known parent package
I have also tried
from project import db, create_app
which gives the error
ModuleNotFoundError: No module named 'project'
I want to know how I can import classes from different directories so that I can use them further in the project.
Thanks in advance
I have the following project structure:
project/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
db.init_app(app)
migrate.init_app(app, db)
return app
run.py
from project import create_app
app = create_app()
if __name__ == "__main__":
app.run()
manage.py
from flask_script import Manager
from flask_migrate import MigrateCommand
from project.models import *
from project import create_app
manager = Manager(create_app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
Yet when I run the following commands, Flask-Migrate is not detecting any tables to be added.
python manage.py db init
Which outputs:
Creating directory $HOME/Project/migrations ... done
Creating directory $HOME/Project/migrations/versions ... done
Generating $HOME/Project/migrations/script.py.mako ... done
Generating $HOME/Project/migrations/env.py ... done
Generating $HOME/Project/migrations/README ... done
Generating $HOME/Project/migrations/alembic.ini ... done
Please edit configuration/connection/logging settings in
'$HOME/Project/migrations/alembic.ini' before proceeding.
and
python manage.py db migrate
Which only outputs:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
Why is Flask-Migrate with Alembic not detecting the Models and therefore creating the tables? Here's what I've tried:
Deleting the database, starting from nothing
Creating a custom db class inside the manage.py file, doesn't detect that
Googling every answer to this problem, found lots of similar questions but none of their solutions worked for me.
EDIT:
Here is an example of the models.py file
from flask import current_app
from project import db
from flask_login import UserMixin
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
The solution was to import the models in the __init__.py file like so:
def create_app():
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
from project import models
db.init_app(app)
migrate.init_app(app, db)
return app
I had the same issue. The solution is pretty same as #joe's
In routes file
from models import User
api_user = Namespace('user', description='user related operations')
In project/__init__.py
def create_app():
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
from project import models
db.init_app(app)
migrate.init_app(app, db)
blueprint = Blueprint('api', __name__, url_prefix=url_prefix)
api = Api(blueprint, doc='/documentation') # ,doc=False
app.register_blueprint(blueprint)
api.add_namespace(api_user)
return app
when adding api_user namespace in create_app flask_migrate detected models
I'm creating a personal application with flask_restful, and I was doing everything with a single models.py and app.py, but the application is going to grow so I decided to make some folder restructuring.
I currently have the following structure:
/project_folder
application_name
__init__.py
controllers.py
models.py
config.py
manage.py
run.py
tests
__init__.py
test_controller.py
Everything works so far, but I want the structure to be the following:
/project_folder
application_name
__init__.py
controllers
__init__.py
brewery_controller.py
...others
models
__init__.py
base_model.py
brewery.py
...others
config.py
manage.py
run.py
tests
__init__.py
test_controller.py
But I can't seem to make it work. Here is the application __init__.py
#/project_folder/application_name/__init__.py
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api
from controllers import BreweryList, BreweryResource
from models import db
def initApp(config):
app = Flask(__name__)
app.config.from_object(config)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
api = Api(app)
api.add_resource(BreweryList, '/breweries')
api.add_resource(BreweryResource, '/breweries/<brewery_id>')
return app
I tried with
from brewery_controller import BreweryList, BreweryResource
from base_model import db
with no luck. I keep getting ImportError: cannot import BreweryList and the same goes for db if I uncomment the Brewery classes import line.
The controllers/__init__.py and models/__init__.py are both empty.
Here is also the run.py
import os
from beerinv import initApp
if __name__ == '__main__':
app = initApp(os.environ['APP_SETTINGS'])
app.run()
Could solve the issue by following #davidism comment by putting full import path:
from application_name.controllers.brewery_controller import BreweryList, BreweryResource
from application_name.models.base_model import db
Here's my file structure:
/
/apitestproject
/models
__init__.py
users.py
items.py
/resources
__init__.py
users.py
items.py
__init__.py
index.py
.deployment
deploy.cmd
requirements.txt
run_waitress_server.py
runserver.py
web.config
Inside my main __init__.py file I have:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
POSTGRES = {
'user': 'admin_user#pracap',
'pw': 'the_password',
'db': 'apitest',
'host': 'pracap.postgres.database.azure.com',
'port': '5432',
}
URL = 'postgresql://{}:{}#{}:{}/{}'.format(POSTGRES['user'], POSTGRES['pw'], POSTGRES['host'], POSTGRES['port'], POSTGRES['db'])
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
import apitestproject.index
In my index.py file I have:
from flask import Flask
from flask_restful import Api
from apitestproject import app, db
#app.before_first_request
def create_tables():
db.create_all()
#app.route('/')
#app.route('/home')
def home():
return "I'm the default route"
And in my /models/users.py file i have:
from apitestproject import db
class UserModel(db.Model):
__tablename__ = 'users'
id = db.column(db.string, primary_key=True)
name = db.column(db.string(50))
address = db.column(db.string(144))
salary = db.column(db.numeric(12, 2))
position = db.column(db.string(50))
password = db.column(db.string(50))
The console is not throwing any errors and I can run everything right without even a single hint of an error. But the tables are not created. Any idea what I might be doing wrong? I've been working with flask/sqlalchemy for just over a month now and I'm starting to work with DB's.
Any help would be appreciated!
I think you will need to work with flask-migrate as a good alternative :
just find this tutorial about it :
a short descrition about it is here :
Migrations allow us to manage changes we make to the models, and
propagate these changes in the database. For example, if later on we
make a change to a field in one of the models, all we will need to do
is create and apply a migration, and the database will reflect the
change.
after installing it via
pip install flask-migrate
edit your init.py like this :
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
POSTGRES = {
'user': 'admin_user#pracap',
'pw': 'the_password',
'db': 'apitest',
'host': 'pracap.postgres.database.azure.com',
'port': '5432',
}
URL = 'postgresql://{}:{}#{}:{}/{}'.format(POSTGRES['user'], POSTGRES['pw'], POSTGRES['host'], POSTGRES['port'], POSTGRES['db'])
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db)
import apitestproject.index
and then edit your index.py by removing the db creatation you will do it via command line .
from flask import Flask
from flask_restful import Api
from apitestproject import app, db
#app.route('/')
#app.route('/home')
def home():
return "I'm the default route"
after that go to your application directory and export the flask app and what are the run script of your app?? :
in cmd do this :
export FLASK_APP=your_runScript.py
and then the 2 following commands to migrate the db :
flask db init
to create the migration folder
and :
flask db migrate
to create the first migration
and :
flask db upgrade
to upgrade changes to the db
find more here about the flask-migrate package
My app layout
my_app
__init__.py
my_app
__init__.py
startup
__init__.py
create_app.py
create_users.py
common_settings.py
core
__init__.py
models.py
views.py
errors
__init__.py
errors.py
Inner __init__.py
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # The WSGI compliant web application object
db = SQLAlchemy(app) # Setup Flask-SQLAlchemy
manager = Manager(app) # Setup Flask-Script
from my_app.startup.create_app import create_app
create_app()
create_app.py
def create_app(extra_config_settings={}):
# Load all blueprints with their manager commands, models and views
from my_app import core
return app
core/__init__.py
# from . import views
views.py
from my_app import app, db
from flask import Flask, request
#app.errorhandler(Error)
def handle_invalid_usage(error):
response = jsonify(data=error.to_dict())
response.status_code = error.status_code
return response
I based this code on a tutorial I found. Everything works fine as long as I leave the __init__.py in the core folder empty.
When I don't, I get a NameError: name Error is not defined in my views.py. Error comes from errors.py.
I have three questions:
1) Why does this happen only when I leave the import statement in core/__init__.py.
2)
create_app.py
app.config.from_envvar('ENV_SETTINGS_FILE')
# Other app.config commands here
from my_app import core
return app
What happens when from my_app import core runs?
3) Finally when I return app, is this to ensure that Inner __init__.py file contains the updated app object?
Any explanations would be greatly appreciated!
Trying to build and configure an app with dynamic imports is really bad news and confusing for the reasons you are discovering. A much better and understandable pattern would be a more typical factory:
def create_app():
app = Flask(__name__)
configure_app(app, config)
register_db(app)
add_views(app)
add_manager(app)
return app
if __name__ == '__main__':
app = create_app()
app.run()
But since you're asking, your problem is here:
from my_app import app, db
from flask import Flask, request
#app.errorhandler(Error) # Error is not imported
def handle_invalid_usage(error):
response = jsonify(data=error.to_dict())
response.status_code = error.status_code
return response
The error occurs because views.py is imported, the code compiler comes across Error and cannot find a reference to it.
For your second question: from my_app import core causes core.__init.__ to run, which (presumably) adds the views onto the app object.