sqlalchemy.orm.exc.UnmappedInstanceError: Class '__builtin__.instance' is not mapped - python

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.

Related

NameError: name 'app' is not defined In Python

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()

db.create_all() not generating db

I'm trying to test Flask with SQLAlchemy and I stumbeld accross this problem. First, I have to note that I read all of the related threads and none of them solves my problem. I have a problem that db.create_all() doesn't generate the table I defined. I have model class in file person.py:
from website import db
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
password = db.Column(db.String)
width = db.Column(db.Integer)
height = db.Column(db.Integer)
agent = db.Column(db.String)
user_data_dir = db.Column(db.String)
And in my website.py which is the file from where I launch the app:
from flask import Flask, jsonify, render_template, request
from flask_sqlalchemy import SQLAlchemy
# create the extension
db = SQLAlchemy()
def start_server(host, port, debug=False):
from person import Person
# create the app
app = Flask(__name__,
static_url_path='',
static_folder='web/static',
template_folder='web/templates')
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database0.db"
# initialize the app with the extension
db.init_app(app)
print('initialized db')
print('creating tables...')
with app.app_context():
db.create_all()
db.session.add(Person(username="example33"))
db.session.commit()
person = db.session.execute(db.select(Person)).scalar()
print('persons')
print(person.username)
if __name__ == '__main__':
start_server(host='0.0.0.0', port=5002, debug=True)
I think the problem might be that the Person class is not importing properly, because when I put the class inside the start_server function it executes fine and creates the table, but I don't know why this is happening. I followed all the advice and imported it before everything, and also I share the same db object between the 2 files
There is probably a better way to do this but this is the only way I could get this to work. You need to create a models.py file or w.e you wanna call it. Then all your database stuff goes in there. The db engine, ALL your models and a function to initialize it all. The reason is, you are having import issues where Person is imported but not fully and so the db doesn't have it in its metadata.
models.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
password = db.Column(db.String)
width = db.Column(db.Integer)
height = db.Column(db.Integer)
agent = db.Column(db.String)
user_data_dir = db.Column(db.String)
# All other models
def initialize_db(app: Flask):
db.init_app(app)
with app.app_context():
db.create_all()
main.py
from flask import Flask
import models
def start_server(host, port, debug=False):
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database0.db"
# initialize the app with the extension
models.initialize_db(app)
db = models.db
with app.app_context():
db.session.add(models.Person(username="example33"))
db.session.commit()
person = db.session.execute(db.select(models.Person)).scalar()
print('persons')
print(person.username)
if __name__ == '__main__':
start_server(host='0.0.0.0', port=5002, debug=True)
I am reading the documentation,
which explains that the function will
Create all tables stored in this metadata.
That leads me to believe Person is not associated with the db metadata.
You mentioned
when I put the class inside the start_server function it ... creates the table
Your from person import Person is nice enough,
but I suspect we wanted a simple import person.
In many apps the idiom would be import models.
Failing that, you may be able to point
create_all in the right direction
with this optional parameter:
tables – Optional list of Table objects, which is a subset of the total tables in the MetaData
Please let us know
what technical approach worked for you.

Creating database via flask in postgreSQL

I m trying a tutorial, to make a database connection with flask, and postgreSQL database using json.
This is the code lines in models.py
from app import db
from sqlalchemy.dialects.postgresql import JSON
class Result(db.Model):
_tablename_= 'results'
id =db.Column(db.Integer, primary_key=True)
url = db.Column(db.String())
result_all = db.Column(JSON)
result_no_stop_words = db.Column(JSON)
def __init__(self, url, result_all, result_no_stop_words):
self.url = url
self.result_all = result_all
self.result_no_stop_words = result_no_stop_words
def __repr__(self):
return '<id {}>'.format(self.id)
Code in config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
DEBUG = False
TESTING = False
CSRF_ENABLED = True
SECRET_KEY = 'this-really-needs-to-be-changed'
SQLALCHEMY_DATABASE_URI = os.environ['postgresql://postgresql:bat123#localhost/DatabaseFirst']
class ProductionConfig(Config):
DEBUG = False
class StagingConfig(Config):
DEVELOPMENT = True
DEBUG = True
class DevelopmentConfig(Config):
DEVELOPMENT = True
DEBUG = True
class TestingConfig(Config):
TESTING = True
Code in manage.py
import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app, db
app.config.from_object(os.environ['APP_SETTINGS'])
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
code in app.py
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
app.config.from_object(os.environ['APP_SETTINGS'])
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
from models import Result
#app.route('/')
def hello():
return "Hello World!"
#app.route('/<name>')
def hello_name(name):
return "Hello {}!".format(name)
if __name__ == "__main__":
app.run()
I want to know before running this code lines should the database be created in postgreSQL, alone with the table, and columns,
Or these code lines creating the table, and columns in postgreSQL
class Result(db.Model):
_tablename_= 'results'
id =db.Column(db.Integer, primary_key=True)
url = db.Column(db.String())
result_all = db.Column(JSON)
result_no_stop_words = db.Column(JSON)
Basically i want to know the function or purpose served by the above set of code lines.(5 code lines)
manager.add_command('db', MigrateCommand) this piece adds a command called db so that you can run flask db which will create the tables and columns.
Note: inorder to use this command first you need to define FLASK_APP in the environment variables.
Eg:
export FLASK_APP=app.py
flask db
Also the model
class Result(db.Model): _tablename_= 'results' id =db.Column(db.Integer, primary_key=True) url = db.Column(db.String()) result_all = db.Column(JSON) result_no_stop_words = db.Column(JSON)
This defines the class representation of the table. It won't create table in database, it's just the representation. The MigrationCommand is responsible for the creation of tables in database.
class Result(db.Model):
__tablename__ = 'results'
id =db.Column(db.Integer, primary_key=True)
class Result(db.Model):
This code line is creating a class instance of Result in front end of Flask application and to pass those values to the Database postgreSQL or whatever respective database you will be using.
__tablename__ = 'results':
Here we are creating a table called results in the database in my case DatabaseFirst
id = db.Column(db.Integer, primary_key=True):
Here we are creating a column called id, in our table called results, which can hold only data of integer type and id column is assigned the primary key of the results table.
Here by the 3 code lines I mentioned above, the database tables and columns are created via the Flask application, and we can see the respective results on postgreSQL database.

Why does my database get reset after each deployment?

I am new to deploying to aws as well as flask. Basically I have a simple Flask app but every time I make a change and deploy the new code to aws elastic beanstalk, the db gets reset.
from dateutil import parser
from datetime import datetime
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_cors import CORS
import os
application = app = Flask(__name__)
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'db.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
ma = Marshmallow(app)
cors = CORS(app)
#app.route('/')
def hello():
return 'hello'
.
.
.
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
weight = db.Column(db.Float)
workouts = db.relationship('Workout', backref='user', lazy=True)
def __init__(self, name, weight):
self.name = name
self.weight = weight
class UserSchema(ma.Schema):
class Meta:
fields = ('id', 'name', 'weight')
user_schema = UserSchema(strict=True)
users_schema = UserSchema(many=True, strict=True)
.
.
.
db.create_all()
if __name__ == '__main__':
app.run(debug=True)
I expect that each time I
eb deploy flask-env my db wouldnt get reset but it does. For instance if i create a user and then later change something in the code and deploy, that user is gone.
You should:
Create an EBS Volume
Load the database into that volume
Attach the EBS Volume to your Beanstalk app with an .ebextension. An example can be found here.
With all that being said, this is not a highly available, well architected solution and will deteriorate at scale rapidly.
You will want to replace SQLite with an RDS instance at some point in the future before it becomes a problem.

Flask Project Structure Change

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.

Categories