Flask SQL Alchemy reflection could not assemble any primary key - python

With Flask SQL Alchemy, I am using the Chinook sqlite db.
sqlalchemy.exc.ArgumentError: Mapper mapped class PlayLists->playlists could not assemble any primary key columns for mapped table 'playlists'
My code is like this. "app/init.py"
from flask import Flask
from config import app_config
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
db = SQLAlchemy()
def create_app(config_name):
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(app_config[config_name])
app.config.from_pyfile('config.py')
db.app = app
db.init_app(app)
db.Model.metadata.reflect(db.engine)
Bootstrap(app)
from app import models
return app
The app/model.py
from app import db
class PlayLists(db.Model):
__tablename__ = db.Model.metadata.tables['playlists']
What am I doing wrong?

In your Playlists class you are assigning db.Model.metadata.tables['playlists'] to __tablename__ . However, db.Model.metadata.tables['playlists'] returns an object of class 'sqlalchemy.sql.schema.Table'. You should instead assign it to a string with the name of the table, as in:
app/model.py
from app import db
class PlayLists(db.Model):
__tablename__ = 'playlists'
This example works for me, returning the column names of the reflected database:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = 'SUPERSECRET'
app.config['SQLALCHEMY_DATABASE_URI'] = ''mysql+pymysql://user:pass#localhost:port/db''
db = SQLAlchemy(app)
db.init_app(app)
db.Model.metadata.reflect(db.engine)
class User(db.Model):
__tablename__ = "users"
#app.route("/")
def hello():
user = User()
table_columns = str(user.__table__.columns)
return table_columns
if __name__ == "__main__":
app.run()

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

Cannot Create tables in a database using SQLAchemy

i have created app.py
and tables.py
which are the main app and a file used to define the tables of a database [database.db] respectively.
I cannot create tables in the database.db, what could be the problem?
Code for both is given below
#app.py
from flask import Flask, render_template, request, session, redirect
from tables import db
from flask_session import Session
app = Flask(__name__)
app.config["SESSION_PERMANENT"] = False
app.config["SESSION_TYPE"] = "filesystem"
Session(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db.init_app(app)
#app.before_first_request
def create_tables():
db.create_all()
#app.route("/")
def home():
return render_template("register.html")
#tables.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class users (db.Model):
users_key = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(21), nullable=False)
email = db.Column(db.String(31), nullable=False, unique=True)
password = db.Column(db.String(61), nullable=False)
i expected to get tables in the database.db file which is located in the same directory as the app.py file. i could not add any tables though.
You have to create database context and initialize it.
with app.app_context():
db.create_all()
Also make sure to import the Flask module from the flask package and SQLAlchemy from the flask_sqlalchemy package in tables.py.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)

Flask_SQLAlchemy modularization issues due ORM

I am trying to build an API using Flask. For database actions I use flask_sqlalchemy.
In my main file, the flask app is initalized. I pass the resulting instance to another file where the configuration is set and to my database module that handles database operations.
main.py:
app = flask.Flask(__name__) # initialize flask app
#initialize modules with app
config.init(app)
database.init(app)
The problem is, the relations I use in the database are in a seperate file and it needs the db object to declare the classes for ORM.
My idea was to declare db and initialize it later in an init function, but that doesn't work in this case, because the db object is undefined when the pythonfile is loaded by an import.
relations.py
db: SQLAlchemy
def init(db):
Relations.db = db
class Series(db.Model):
"""Representation of a series
"""
id = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
class User(db.Model):
"""Representation of a user
"""
id = db.Column(db.INT, primary_key=True)
name = db.Column(db.String(255))
class Subscription(db.Model):
"""Representation of a subscription
"""
series_id = db.Column(db.INT, primary_key=True)
user_id = db.Column(db.String(255), primary_key=True)
My database module uses the way and it works fine(init.py file):
db: SQLAlchemy
def init(app):
database.db = SQLAlchemy(app)
# handle database operations...
One approach to solve the issue is just using another instance in the relations.py like that:
app = flask.Flask(__name__)
db = SQLAlchemy(app)
# declare classes...
I tried it out and it workes, but that is not a nice way to solve this and leads to other problems.
Importing it from main does also not work because of circular import.
I have no idea how to smoothly solve this without removing modularization. I would be thankful for any inputs. If I should add any further information, just let me know.
I would create the app variable in your main.py file but leave out the initializing part. From there you call a function from init.py to basically set up the database. That is what I did for my last flask project.
Main.py:
from init import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
Init.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
db.init_app(app)
create_database(app)
#Other operations ...
return app
Relations.py
from init import db
#all your classes ...
db.create_all()
So now you can import the db object to your relations.py file from the init.py.

Flask SQL Alchemy create_all doesn't create any tables

I was working on my school project which required me to develop an API on Flask. I was using MySQL with Flask SQLAlchemy. After I finished the project I haven't touched it in a month. When I came back and tried to run it I found out that it doesn't create tables on its own.
What I checked:
MySQL user has all permitions
App does connect to the database
Every model has table name defined
app.py file:
import logging
from os import environ
from flask import Flask
from flask_cors import CORS
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy
from config import DevConfig, ProdConfig
db = SQLAlchemy()
def create_app():
from resources import Area, Map, Ping, SensorData
env = environ.get('ENVIRONMENT')
if env == 'DEVELOPMENT':
Config = DevConfig
else:
Config = ProdConfig
app = Flask(__name__)
app.config.from_object(Config())
CORS(app)
logging.basicConfig(
filename='app.log',
level=logging.INFO
)
api = Api(app)
api.add_resource(Area, '/area')
api.add_resource(Map, '/map')
api.add_resource(SensorData, '/api/v1/saveSensorData')
api.add_resource(Ping, '/ping')
db.init_app(app)
with app.app_context():
from models import AreaModel, SensorDataModel
db.create_all()
return app
if __name__ == '__main__':
app = create_app()
app.run(host='0.0.0.0', port=8080)
One of the models:
from app import db
from datetime import datetime
class AreaModel(db.Model):
__tablename__ = 'area_records'
id = db.Column(
db.Integer,
primary_key=True
)
aqi = db.Column(
db.Integer,
)
latitude = db.Column(
db.String(16),
)
longitude = db.Column(
db.String(16),
)
created = db.Column(
db.DateTime,
default=datetime.now()
)
I found a solution, but not an answer. For some reason, when I run app.py directly using python app.py it won't create any tables. But when I created run.py with this code:
from app import create_app
app = create_app()
app.run(host='0.0.0.0', port=8080)
It worked! I hope someone can explain it but I'm really happy I got the solution.

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.

Categories