I cannot create tables using SQLAlchemy - python

Following this tutorial of using SQLAlchemy and Postgresql, I based myself for creating a file structure of models, views, templates etc..
requirements.txt
run.py
website/
__init__.py
views/
models/
users.py
static/
templates/
As you can see, inside models I have users.py
from app import db
class Users(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(), index=True, unique=True)
password = db.Column(db.String(128))
def __init__(self, user, password):
self.user = user
self.password= password
def __repr__(self):
return f"<User {self.user}>"
My init.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://postgres:postgres#localhost:5432/project"
db = SQLAlchemy(app)
migrate = Migrate(app, db)
#Routes
#app.route("/")
def index():
return render_template('index.html')
Now, I used these commands to create user table flask db init, flask db migrate, flask db upgrade. OK, after this, was created a table named public.alembic_version, but as you see, Users didnt.
My last tried, was insert this import from models import users between:
migrate = Migrate(app, db)
from models import users
#app.route("/")
def index():
return render_template('index.html')
But the message is ModuleNotFoundError: No module named 'models' I thought that I'm using a reserved word, even changing folder, page name, the error keeps, just change module name.
Update:
Final result, this example work to me
run.py
from website import app
from website.models.users import User
app.run(host="0.0.0.0",debug=True,port=5000)
Update
requirements.txt
run.py
website/
__init__.py
views/
models.py
static/
templates/
What I changed is remove Models Folder e create a file models.py and adding the class Users, Purchase, anything that I want...
I took these imports and include in top of my models.py...
from website import app
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
import psycopg2
app.config['SQLALCHEMY_DATABASE_URI'] = "postgres://postgres:password#ipaddress:5432/databasename"
db = SQLAlchemy(app)
migrate = Migrate(app, db)
In __init__.py added in end of line, after blueprints imports, if I wanted do it, from website.models import Users
from flask import Flask, render_template
app = Flask(__name__)
from website.models import Usuario

The only problem I can find is that you add an import statement (from models import users) in your last attached part of the code. However, you have not created an __init__.py inside your models folder, to declare it as a module. So, that you can import it later as a module like you have created an __init__.py file in your main directory ("website/"). But how you import the models.py file in your run.py file? In your run.py file you should import the models like from website.models.users import Users.
I have two working projects, where I also use FlaskSQLAlchemy & PostgreSQL, but I have set as the SQLALCHEMY_DATABASE_URI = 'postgres://postgres:[password]#localhost:5432/[database_name]'. It works perfectly fine by putting postgres instead of postgresql for the engine configuration.
Reference: Flask-SQLAlchemy import/context issue
UPDATE
Well, you have put your business login (routes, ...) in the init.py file. If you want it to run, I think you should probably put it in the run.py file. Leave the __init__.py files empty.
Furthermore, in your app.py file import your models like this: from .website.models import Users. This requires that you have three __init__.py files. One in your main directory where app.py is located, one in the website folder, and one in the models folder.
*I hope that helps. Please let me know if this works, and if there is anything else I can help you with.

Related

Flask Application Circular Dependencies

I am developing a Flask application, and I am not sure why I am getting this error:
File "app.py", line 17, in <module>
from endpoints.users.resource import UserResource
File "{basedir}/endpoints/users/resource.py", line 4, in <module>
from .model import User
File "{basedir}/endpoints/users/model.py", line 1, in <module>
from app import db
File "{basedir}/app.py", line 17, in <module>
from endpoints.users.resource import UserResource
ImportError: cannot import name 'UserResource' from 'endpoints.users.resource' ({basedir}/endpoints/users/resource.py)
I believe it is due to a circular dependency, from looking at the error, but I can't figure out why, because I think that the order in which I am importing things in my code should have circumvented this issue:
app.py:
from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
api = Api(app)
api.prefix = '/api'
from endpoints.users.resource import UserResource
api.add_resource(UserResource, '/users')
if __name__ == '__main__':
app.run(host="0.0.0.0")
endpoints/users/model.py:
from app import db
class User(db.Model):
# info about the class, requires db
endpoints/users/resource.py:
from flask_restful import Resource
from .model import User
from app import db
class UserResource(Resource):
def get(self, username=None):
# get request, requires db and User
In app.py, since I am importing from endpoints.users.resource after db is created, shouldn't that circumvent the circular dependency?
In addition, I can run this with flask run but when I try to use python app.py, then it gives me the above error. Why would these give different results?
So on from endpoints.users.resource import UserResource line python tries to import from app import db line to app.py which causes app reference to itself, which is not good at all.
One workaround to solve circual import errors in Flask is using init_app function which exists in most of Flask apps. So just create database file like this:
database.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app.py
from flask import Flask
from flask_restful import Api
from database import db
from endpoints.users.resource import UserResource
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
api = Api(app)
api.prefix = '/api'
api.add_resource(UserResource, '/users')
if __name__ == '__main__':
app.run(host="0.0.0.0")
endpoints/users/model.py:
from database import db
class User(db.Model):
# info about the class, requires db
endpoints/users/resource.py:
from flask_restful import Resource
from endpoints.users.model import User
from database import db
class UserResource(Resource):
def get(self, username=None):
# get request, requires db and User
Note that I rewrote your imports from related, so don't forget to add __init__.py files
Your structure will be like this:
.
├── app.py
└── database.py/
└── endpoints/
├── __init__.py
└── users/
├── __init__.py
├── model.py
└── resource.py

Trying to run the sql-alchemy tutorial steps. Can't import db from console (ImportError: cannot import name 'db')

Trying to run the tutorial here: http://flask-sqlalchemy.pocoo.org/2.1/quickstart/ using my app
I have looked at the circular imports problem but I don't think that's it. I'm an absolute beginner to python and flask (and sqlalchemy). My app currently runs, but the database part doesn't
This is the current setup:
mysite
|- __init__.py
|- flask_app.py
|- models.py
|- views.py
init.py
from flask import Flask
app = Flask(__name__)
flask_app.py
from flask import Flask, request, url_for
import random
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql:// -- database uri --'
... app continues here
models.py
from app import app
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class Foo(db.Model):
... model continues here
views.py
from app import app,models
... views continue here, still not using anything from models
when I run from mysite import db in the python console I get:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'db'
Declare your db object in __init__.py. The stuff that is declared in __init__.py defines what can be imported under mysite/.
See: What is __init__.py for?
Also consider moving to the application factory pattern.
For example in __init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['DEBUG'] = True
... more application config ...
db.init_app(app)
return app
Then in flask_app.py:
from mysite import create_app, db
app = create_app()
if __name__ == '__main__':
app.run()
I point this out because you instantiate the app object twice in the code you've shown. Which is definitely wrong.

How to structure Flask User app?

I use supervisor to run my app. It is structured as follows:
My app layout
my_app
__init__.py
my_app
__init__.py
startup
create_app.py
create_users.py
common_settings.py
core
__init__.py
models.py
views.py
Outer __init__.py
from my_app import app
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={}):
"""
Initialize Flask applicaton
"""
# ***** Initialize app config settings *****
# Read common settings from 'app/startup/common_settings.py' file
app.config.from_object('app.startup.common_settings')
# Read environment-specific settings from file defined by OS environment variable 'ENV_SETTINGS_FILE'
app.config.from_envvar('ENV_SETTINGS_FILE')
# Load all blueprints with their manager commands, models and views
# Setup Flask-User to handle user account related forms
from my_app.core.models import User
# Setup Flask-User
db_adapter = SQLAlchemyAdapter(db, User) # Setup the SQLAlchemy DB Adapter
user_manager = UserManager(db_adapter, app) # Init Flask-User and bind to app
from my_app import core
return app
my_app/core/__init__.py
from . import models
from . import views
views.py
from my_app import db, app
'''
Register a new user
'''
#app.route('/register', methods = ['POST'])
def register_user():
user_manager = app.user_manager
db_adapter = user_manager.db_adapter
I was trying to follow an example I found online.
I'm creating the variables db_adapter and user_manager in create_app(). Are these the same ones being used in my views.py?
If anyone has any suggestions or links to examples that I can follow to structure my project, it would be greatly appreciated.
Thanks.
Assuming that that's how Flask-User works (sets the user_manager attribute on app), this is trivial to determine, just compare them in the create_app function when you still have a direct reference to the objects.
db_adapter = SQLAlchemyAdapter(db, User)
user_manager = UserManager(db_adapter, app)
assert db_adapter is user_manager.db_adapter
assert user_manager is app.user_manager
However, your entire project layout doesn't make much sense. You should be creating the entire app inside the create_app factory. You should not have an __init__.py file at the top level, that's the project folder not the package. You should use current_app within views to access the app, since it will only be created at runtime by the factory. You should create a manage.py file at the project level to use the factory.
my_project/
my_app/
__init__.py
models.py
views.py
defaults.py
instance/
config.py
manage.py
__init__.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__, instance_relative_config=True)
app.config.from_object('my_app.defaults')
app.config.from_pyfile('config.py')
db.init_app(app)
from my_app.views import bp
app.register_blueprint(bp)
return app
models.py:
from my_app import db
class User(db.Model):
...
views.py:
from flask import Blueprint, render_template
from my_app.models import User
bp = Blueprint('app', __name__)
#bp.route('/')
def index():
return render_template('index.html')
manage.py:
#!/usr/bin/env python
from flask_script import Manager
from my_app import create_app
Manager(create_app).run()

Flask/PyMongo - Initialize pymongo at the top of the app

I'm trying to scale up my first Flask app and am not understanding the structure needed to use a pymongo db in multiple modules. For example, here is my new structure:
run.py
app/
├── __init__.py
├── forms.py
├── static/
├── templates/
└── views/
├── __init__.py
├── bookmarklet.py
├── main.py
└── user.py
Prior to trying to scale this, I had this at the top of my single views.py file:
from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
mongo.db.user.ensure_index("email", unique=True)
The goal is to be able to use this mongo instance in all of the view modules as well as the forms.py module. I've tried these two things:
Put the above snippet in the app/__init__.py file, but can't seem to make it accessible to any other modules. I tried doing this: app.db = mongo.db (but it wasn't available downstream)
Put the above snippet into each module that needs it, but then I get the error that there are multiple mongo instances with the same prefix.
Where should this initialization go in order to make it accessible everywhere in the app?
EDIT
It sounds like I'm doing it right but there is something else going on. I'm posting my more complete code and error.
app/__init__.py
from flask import Flask
app = Flask(__name__)
from app.views import main
app.config.update(
DEBUG = True,
SECRET_KEY = "not telling",
WTF_CSRF_ENABLED = False,
)
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
mongo.db.user.ensure_index("email", unique=True)
app/views/main.py
from app import app
from flask import render_template, redirect, request, flash, url_for
from flask.ext.jsonpify import jsonify
from app.forms import *
from app import *
print mongo
Error:
(venv)imac: me$ ./run.py
Traceback (most recent call last):
File "./run.py", line 4, in <module>
from app import app
File "/Users/me/Dropbox/development/test/app/__init__.py", line 4, in <module>
from app.views import main
File "/Users/me/Dropbox/development/test/app/views/main.py", line 9, in <module>
print mongo
NameError: name 'mongo' is not defined
Put that snippet in app/__init__.py. If you want to access it in forms.py, for instance, try:
...
from app import *
# then you can use mongo here
print mongo
...
If you want to access it in user.py, for instance, try the same code above.
Check if this works for you. If not, show me the error message and I will think about solution two.
SOLVED
The mistake in my __init__.py file was that I was importing my views to early. You have to do that at the end!
WRONG
from flask import Flask
app = Flask(__name__)
from app.views import main # <- TOO EARLY
app.config.update(
DEBUG = True,
SECRET_KEY = "not telling",
WTF_CSRF_ENABLED = False,
)
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
from flask.ext.pymongo import PyMongo
mongo = PyMongo(app)
with app.app_context():
mongo.db.user.ensure_index("email", unique=True)
RIGHT
from flask import Flask
from flask.ext.pymongo import PyMongo
app = Flask(__name__)
mongo = PyMongo(app)
with app.app_context():
mongo.db.user.ensure_index("email", unique=True)
app.config.update(
DEBUG = True,
SECRET_KEY = "not telling",
WTF_CSRF_ENABLED = False,
)
app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
# AT THE BOTTOM!
from app.views import main

Structure of a Flask app with more than one models.py

I currently have a Flask app with the following structure:
deploy/
api/
customer/
models.py
contact/
models.py
campaign/
models.py
activity/
models.py
__init__.py
database.py
tests/
test_api.py
Because I have so many models, I have split them out into separate files which is causing me issues when I try and initialise my DB.
In each one of my models, I do the following to make Flask-SQLAlchemy's Model call available:
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
...
Doing it this way means there's a different db object for every model which makes it impossible to initialise my app properly.
How can I structure my project so I can have one db object that is used by all my models, tests and my create_app() function in __init__.py?
Here's one way:
myapp/
__init__.py
database.py
app.py
model1/
__init__.py
models.py
model2/
__init__.py
models.py
In the database.py:
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
In the various models.py files:
from ..database import db
class User(db.Model):
...
This makes use of explicit relative imports

Categories