Hello I have a finished Flask/Flask-SqlAlchemy app working correctly but I wanted to reorganize its structure according to:
http://flask.pocoo.org/docs/0.10/patterns/packages/
My working project has the following structure and files:
folder:monkeyMeRoundTwo:
-app.py
-config.py
-models.py
-monkeyDB.db
-app_test.py
folder:templates:
-edit.html
-friends.html
-layout.html
-login.html
-myProfile.html
-profile.html
-register.html
-users.html
folder:static:
folder:css
folder:images
My app.py file:
from flask import Flask, render_template, redirect, \
url_for, request, session, flash
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
# local
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///monkeyDB.db'
# heroku
#import os
app.config.from_object('config.BaseConfig')
#app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
from models import *
#app.route('/')
def index():
if not session.get('logged_in'):
return render_template('login.html')
else:
return redirect(url_for('friendList'))
.......rest of views
if __name__ == '__main__':
app.run(debug=True)
My config.py file:
import os
class BaseConfig(object):
SECRET_KEY = "kjdsbfkjgdf78sft"
My models.py file:
from app import db
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
class users(db.Model):
__tablename__ = "Users"
id = db.Column(db.Integer, primary_key=True)
userName = db.Column(db.String, nullable=False)
userEmail = db.Column(db.String, nullable=False)
userPhone = db.Column(db.String, nullable=False)
userPass = db.Column(db.String, nullable=False)
def __init__(self, userName, userEmail, userPhone, userPass):
self.userName = userName
self.userEmail = userEmail
self.userPhone = userPhone
self.userPass = userPass
def __repr__(self):
return '{}-{}-{}-{}'.format(self.id, self.userName, self.userEmail, self.userPhone)
class friendships(db.Model):
__tablename__ = "Friendships"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=False)
friend_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=False)
userR = db.relationship('users', foreign_keys='friendships.user_id')
friendR = db.relationship('users', foreign_keys='friendships.friend_id')
def __init__(self, user_id, friend_id):
self.user_id = user_id
self.friend_id = friend_id
def __repr__(self):
return '{}-{}-{}-{}'.format(self.user_id, self.friend_id)
class bestFriends(db.Model):
__tablename__ = "BestFriends"
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=False)
best_friend_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=False)
user = db.relationship('users', foreign_keys='bestFriends.user_id')
best_friend = db.relationship('users', foreign_keys='bestFriends.best_friend_id')
def __init__(self, user_id, best_friend_id):
self.user_id = user_id
self.best_friend_id = best_friend_id
def __repr__(self):
return '{}-{}-{}-{}'.format(self.user_id, self.best_friend_id)
My app_tests.py file:
import os
import app
import unittest
import tempfile
class AppTestCase(unittest.TestCase):
def setUp(self):
self.db_fd, app.app.config['DATABASE'] = tempfile.mkstemp()
app.app.config['TESTING'] = True
self.app = app.app.test_client()
def tearDown(self):
os.close(self.db_fd)
os.unlink(app.app.config['DATABASE'])
def test_index_page(self):
rv = self.app.get('/')
assert 'Friends' in rv.data
...........rest of tests
if __name__ == '__main__':
unittest.main()
As I mentioned everything works fine and the tests pass all ok but when I attempt to follow the example on:
http://flask.pocoo.org/docs/0.10/patterns/packages/
and change the project to the following structure:
Structure/organization:
folder:monkeyMeRT:
-runserver.py
folder:monkeyMeRT:
-__init__.py
-views.py
-config.py
-models.py
-monkeyDB.db
-app_test.py
folder:templates:
-edit.html
-friends.html
-layout.html
-login.html
-myProfile.html
-profile.html
-register.html
-users.html
folder:static:
folder:css
folder:images
runserver.py file:
from monkeyMeRT import app
app.run(debug=True)
init.py file:
from flask import Flask, render_template, redirect, \
url_for, request, session, flash
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
# local
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///monkeyDB.db'
# heroku
#import os
app.config.from_object('config.BaseConfig')
#app.config.from_object(os.environ['APP_SETTINGS'])
db = SQLAlchemy(app)
from models import *
import monkeyMeRT.views
views.py file:
from monkeyMeRT import app
.......here go all the views/functions
models.py file:
from monkeyMeRT import db
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
........here go the db classes
config.py file:
import os
class BaseConfig(object):
SECRET_KEY = "kjdsbfkjgdf78sft"
After changes I end up with errors.
Traceback (most recent call last):
File "__init__.py", line 19, in <module>
from models import *
File "/Users/alex/Desktop/PY/monkeyMeRT/monkeyMeRT/models.py", line 1, in <module>
from monkeyMeRT import db
ImportError: No module named monkeyMeRT
I guess I haven't interpreted the example correctly. Would anyone be able to help me out with this I am new to Flask(started learning a month ago) and would like to have an efficient setup of the project with config and views separated like in the example:
http://flask.pocoo.org/docs/0.10/patterns/packages/
Help is very much appreciated!
Thanks in advance.
The traceback is telling you that monkeyMeRT is not a package. To fix this:
Be sure to name your project folder monkeyMeRT
monkeyMeRT needs to contain a file called __init__.py
That init file doesn't have to contain anything, it just needs to exist so that Python knows to treat the directory as a Python package.
Related
I am new to flask and i have been struggling to create an sqlite database but whenever i run the from app import db I get the error message:
NameError: name 'app' is not defined
This is my code:
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
db = SQLAlchemy()
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db.init_app(app)
class Todo:
id = db.Column(db.Integer(), primary_key=True)
content = db.Column(db.String(length=300), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return '<Task %r>' % self.id
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)`
The image below is my directory structure. I don't know if it has anything to do with it: Image of directory structure
I tried import db from app so that I will create the db file.
First u need to replace db.init_app(app) with db = SQLAlchemy(app). The starting code could look like this:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
Then after your class Todo:
with app.app_context():
db.create_all()
This question already has an answer here:
Flask-SQLAlchemy db.create_all() got an unexpected keyword argument 'app'
(1 answer)
Closed 4 months ago.
I am attempting to create a Flask app where users can register / login and have their own page (following a tutorial on YT) - I am quite new to this and am struggling to understand the error message that I am receiving.
Error Message:
Traceback (most recent call last):
File "C:\Users\mmacp\PycharmProjects\cfg_project\main.py", line 11, in <module>
app = create_app()
File "C:\Users\mmacp\PycharmProjects\cfg_project\website\__init__.py", line 25, in create_app
create_database(app)
File "C:\Users\mmacp\PycharmProjects\cfg_project\website\__init__.py", line 32, in create_database
db.create_all(app)
File "C:\Users\mmacp\AppData\Local\Programs\Python\Python310\lib\site-packages\flask_sqlalchemy\extension.py", line 868, in create_all
self._call_for_binds(bind_key, "create_all")
File "C:\Users\mmacp\AppData\Local\Programs\Python\Python310\lib\site-packages\flask_sqlalchemy\extension.py", line 837, in _call_for_binds
for key in keys:
TypeError: 'Flask' object is not iterable
main.py:
from website import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
init.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kdxhfds iefhsdbf'
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
from .views import views
from .auth import auth
app.register_blueprint(views, url_prefix='/')
app.register_blueprint(auth, url_prefix='/')
from .models import User, Posts
create_database(app)
return app
def create_database(app):
if not path.exists('website/' + DB_NAME):
db.create_all(app)
print('Created Database!')
models.py
from website import db
from flask_login import UserMixin
from sqlalchemy.sql import func
class Posts(db.Model):
id = db.Column(db.Integer, primary_key=True)
data = db.Column(db.String(500))
date = db.Column(db.DateTime(timezone=True), default=func.now)
user_id = db.Column(db.Integer, db.ForeignKey('user.id')) # refs the User table
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
username = db.Column(db.String(150), unique=True)
password = db.Column(db.String(150))
first_name = db.Column(db.String(150))
surname = db.Column(db.String(150))
fav_team = db.Column(db.String(150))
notes = db.relationship('posts')
I have tried to reformat the database User and Posts classes and have attempted some minor tweaks which haven't helped - currently at a bit of a loss as to what I should do next.
Usually I can eventually figure these things out but my heads a bit fried!!
I have solved this by adding a piece of code to the create_app() function in the init.py file:
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'kdxhfds iefhsdbf'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///databse.db'
db.init_app(app)
***with app.app_context():
db.create_all()***
I was trying to package my code as it was getting kind of complex for me to keep in one file and i encountered an import error when i tried to run the file that says circular import error, how do i solve this error? I have been analyzing the code and i cannot seem to be able to figure out what might be wrong.
run.py
from market import app
if __name__ == "__main__":
app.run(debug=True)
init.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from market import routes
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///market.db"
db = SQLAlchemy(app)
routes.py
from market import app
from flask import render_template
from market.models import Item
#app.route("/")
#app.route("/home")
def home():
return render_template("index.html")
#app.route("/market")
def market():
items = Item.query.all()
return render_template("market.html", items=items)
models.py
from market import db
class Item(db.Model):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(length=30), nullable=False, unique=True)
price = db.Column(db.Integer(), nullable=False)
barcode = db.Column(db.String(length=12), nullable=False, unique=True)
description = db.Column(db.String(length=1024), nullable=False, unique=True)
def __repr__(self):
return f"Item {self.name}"
project structure
error
Moving your routes import to the bottom of the file should help.
Just as you would do for example with blueprints in application factory. You import blueprints/views after you create app instance with app = Flask(__name__):
def create_app(config_filename):
app = Flask(__name__)
app.config.from_pyfile(config_filename)
from yourapplication.model import db
db.init_app(app)
from yourapplication.views.admin import admin
from yourapplication.views.frontend import frontend
app.register_blueprint(admin)
app.register_blueprint(frontend)
return app
Also check:
Is a Python module import at the bottom ok?
in your __init__.py you import routes
in routes.py you import app (defined in __init__.py)
I'm new to Python and still learning the basics. When running my program, it returns this error and I can't find the solution to this.
My codes are as follows:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
...
class Illness:
__tablename__ = "list_illnesses"
id = db.Column(db.Integer, primary_key=True)
illness = db.Column(db.String, nullable=False)
def __init__(self, illness):
self.illness = illness
import csv
import os
from flask import Flask, render_template, request
from models import *
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db.init_app(app)
def main():
f = open("illnesses.csv")
reader = csv.reader(f)
for name in reader:
foo = Illness(illness=name[0])
db.session.add(foo)
db.session.commit()
if __name__ == "__main__":
with app.app_context():
main()
illnesses.csv only contains one illness name per line. I have been searching for hours but I can't seem to find the problem.
It's probably significant that
class Illness:
isn't a subclass of db.Model.
I'm using Flask and SQLAlchemy. I have used my own abstract base class and inheritance. When I try to use my models in the python shell I get the following error:
>>> from schedule.models import Task
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/teelf/projects/schedule/server/schedule/models.py", line 14, in <module>
class User(Base):
File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/flask_sqlalchemy/__init__.py", line 536, in __init__
DeclarativeMeta.__init__(self, name, bases, d)
File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/ext/declarative/api.py", line 55, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 254, in _as_declarative
**table_kw)
File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/sql/schema.py", line 393, in __new__
"existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'user' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns
on an existing Table object.
How do I fix this?
Code:
manage.py:
#!/usr/bin/env python
import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.script import Manager
from server import create_app
from database import db
app = create_app("config")
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command("db", MigrateCommand)
if __name__ == "__main__":
manager.run()
__init__.py:
from flask import Flask
from flask.ext.login import LoginManager
from database import db
from api import api
from server.schedule.controllers import mod_schedule
def create_app(config):
# initialize Flask
app = Flask(__name__)
# load configuration file
app.config.from_object(config)
# initialize database
db.init_app(app)
api.init_app(app)
# initialize flask-login
login_manager = LoginManager(app)
# register blueprints
app.register_blueprint(mod_schedule)
return app
database.py:
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
models.py:
from sqlalchemy.dialects.postgresql import UUID
from database import db
class Base(db.Model):
__abstract__ = True
id = db.Column(UUID, primary_key=True)
class User(Base):
__tablename__ = "user"
username = db.Column(db.String)
password = db.Column(db.String)
first_name = db.Column(db.String)
last_name = db.Column(db.String)
authenticated = db.Column(db.Boolean, default=False)
def __init__(self, first_name, last_name, username):
self.first_name = first_name
self.last_name = last_name
self.username = username
def is_active(self):
""" All users are active """
return True
def get_id(self):
return self.username
def is_authenticated(self):
return self.authenticated
def is_anonymous(self):
""" Anonymous users are not supported"""
return False
controllers.py:
from flask import Blueprint
from flask.ext.restful import reqparse, Resource
from api import api
from server.schedule.models import User
mod_schedule = Blueprint("schedule", __name__, url_prefix="/schedule")
class Task(Resource):
def put(self):
pass
def get(self):
pass
def delete(self):
pass
api.add_resource(Task, "/tasks/<int:id>", endpoint="task")
Try adding
__table_args__ = {'extend_existing': True}
to your User class right under __tablename__=
cheers
Another option, if you don't already have data in your pre-existing database, is to drop it, recreate it without the tables. Then interactively run your "models.py" script (you would need to add a little code at the bottom to allow this), then in the interactive Python console do "db.create_all()" and it should create the tables based on your classes.
I had the same problem and found the solution here:
https://github.com/pallets-eco/flask-sqlalchemy/issues/672#issuecomment-478195961
So, basically we hit the union of two problems:
Having left over .pyc files on the disk.
Git Ignoring empty directories full of files in .gitignore
Deleting the directories and cleaning the .pyc files solved the problem.