Get list of all relationships from a table Flask SQLalchemy - python

I'm trying to get a list of all the relationships for a table with Flask SQLAlchemy, but don't see any option, just on how to create relationships.
Does anyone know how I can do this? Any help is much appreciated.
Here is a simple example of 3 models. How can I get a list of the two relationships from the Member model?
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
import os
from flask_login import UserMixin
app = Flask(__name__)
file_path = os.path.abspath(os.getcwd()) + "\database.db"
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + file_path
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECRET_KEY"] = "my secret!"
db = SQLAlchemy(app)
class Member(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(40), unique = True)
hobbies = db.relationship("Hobbies", backref="member", lazy="dynamic")
friends = db.relationship("Friends", backref="member", lazy="dynamic")
def __init__(self, name):
self.name = name
def __repr__(self):
return "<Member {}>".format(self.id)
class Hobbies(db.Model):
id = db.Column(db.Integer, primary_key = True)
hobby = db.Column(db.String(40))
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
def __init__(self, hobby, user_id):
self.hobby = hobby
self.user_id = user_id
def __repr__(self):
return "<Hobbies {}>".format(self.id)
class Friends(db.Model):
id = db.Column(db.Integer, primary_key = True)
friend = db.Column(db.String(40))
user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
def __init__(self, friend, user_id):
self.friend = friend
self.user_id = user_id
def __repr__(self):
return "<Friends {}>".format(self.id)

from sqlalchemy.inspection import inspect
relations = inspect(Member).relationships.items()

Related

Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS

I am trying to create an API in Python that uses a Postgresql database. I am attempting a simple endpoint to pull to check to see if the database can connect and pull data. I am probably missing something simple and need someone to point it out. Below is my main.py file
import psycopg2
import model
import os
from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy
uname = os.environ['uname']
pas = os.environ['pas']
url = os.environ['url']
port = os.environ['port']
dbase = os.environ['dbase']
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://' + uname + ':' + pas + '#' + url + ':' + port + '/' + dbase
db = SQLAlchemy(app)
#app.route('/test')
def test():
tst = model.Doc.query.filter_by(doc_num=1).first()
return jsonify(tst)
if __name__ == '__main__':
app.run()
I also have a model.py file where my database is modeled out.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import Column, Integer, String, Date, ForeignKey
from flask_marshmallow import Marshmallow
app = Flask(__name__)
db = SQLAlchemy(app)
ma = Marshmallow(app)
class Aud(db.Model):
__tablename__ = 'aud'
__table_args__ = {'schema': 'cirsx'}
aud_num = Column(Integer, primary_key=True)
aud_name = Column(String, nullable=False, unique=True)
aud_desc = Column(String)
class AudSchema(ma.Schema):
class Meta:
fields = ('aud_num', 'aud_name', 'aud_desc')
class DocTyp(db.Model):
__tablename__ = 'doctyp'
__table_args__ = {'schema': 'cirsx'}
doctyp_num = Column(Integer, primary_key=True)
doctyp_name = Column(String, nullable=False, unique=True)
doctyp_desc = Column(String)
class DocTypSchema(ma.Schema):
class Meta:
fields = ('doctyp_num', 'doctyp_name', 'doctyp_desc')
class Doc(db.Model):
__tablename__ = 'doc'
__table_args__ = {'schema': 'cirsx'}
doc_num = Column(Integer, primary_key=True)
doctyp_num = Column(Integer, ForeignKey('doctyp_num'))
aud_num = Column(Integer, ForeignKey('aud_num'))
doc_path = Column(String, nullable=False)
title = Column(String, nullable=False)
author = Column(String)
keywords = Column(String)
pub_dt = Column(Date)
doc_abs = Column(String)
doc_txt = Column(String)
class DocSchema(ma.Schema):
class Meta:
fields = ('doc_num',
'doctyp_num',
'aud_num',
'doc_path',
'title',
'author',
'keywords',
'pub_dt',
'doc_abs',
'doc_txt')
aud_schema = AudSchema()
aud_schemas = AudSchema(many=True)
doctyp_schema = DocTypSchema()
doctyp_schemas = DocTypSchema(many=True)
doc_schema = DocSchema()
doc_schemas = DocSchema(many=True)
if __name__ == '__main__':
app.run()
Is there something that I am missing to why I am getting this error?

Unable to store data in sqlite db with Python / SQLAlchemy (Flask)

Hello I'm struggling with this error since weeks.
In my python/flask app I need to store a pw in a db table user in SQLite with SQLalchemy.
The table seemds to be correctly created when I check sqlite> .schema the column pwd is there.
When I run the app it returns an error saying the column pwd does not exist (see error below).
I tried several times dropping the table, trying in a new db but nothing, I think the table is created correctly but there must be something wrong in the code? Could also be the db that was messed up but I don't think so.
Here I create the table and define the User class, as per official SQLAlchemy documentation
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from sqlalchemy import *
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data-users.sqlite'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer(), primary_key = True, autoincrement=True)
username = db.Column(db.String(64), unique = True)
pwd = db.Column(db.String())
def __repr__(self):
return '<User %r>' % self.username
Here I store the user data in the table
from store_user_db import User, db
db.create_all()
DICP_FTP_DESTINATION_PSW=self.submit_pwd()
user = User(id=001,username="ita_itf",pwd=DICP_FTP_DESTINATION_PSW)
db.session.add(user)
db.session.commit()
This is the error:
sqlalchemy.exc.OperationalError
OperationalError: (sqlite3.OperationalError) table user has no column named pwd
[SQL: INSERT INTO user (id, username, pwd) VALUES (?, ?, ?)]
[parameters: (1, 'ita_itf', <read-only buffer for 0x7efe495709f0, size -1, offset 0 at 0x7.....
I don't have much experience flask and SQlAlchemy, but here is a sample app which is working for me.
The Model definitions are taken from the documentation and added a test model during runtime to see if it is still able to create new tables and it did.
If you have a large app, I'd prefer to use flask-migrate library which can create versioned migrations from your models for creating/modifying your tables.
from datetime import datetime
from flask import Flask, request, flash, url_for, redirect, json
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return '<User %r>' % self.username
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
def __repr__(self):
return '<Category %r>' % self.name
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80), nullable=False)
body = db.Column(db.Text, nullable=False)
pub_date = db.Column(db.DateTime, nullable=False,
default=datetime.utcnow)
category_id = db.Column(db.Integer, db.ForeignKey('category.id'),
nullable=False)
category = db.relationship('Category',
backref=db.backref('posts', lazy=True))
def __repr__(self):
return '<Post %r>' % self.title
class Test(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
def __repr__(self):
return '<Test %r>' % self.name
def insertAdminUser():
admin = User(username='admin', email='admin#example.com')
db.session.add(admin)
db.session.commit()
#app.route('/insert-admin', methods = ['GET'])
def insertAdmin():
insertAdminUser()
return app.response_class(
response=json.dumps({
"message": "inserted"
}),
mimetype='application/json'
)
if __name__ == '__main__':
db.create_all()
app.run(debug = True)

ForeignKey is always OFF and not working between tables in SQLalchemy in Flask

my code for db in Flask and SQLalchemy is working but when I make comment in post, ForeignKey doesn't link comment with that post and there is no value for post_id in table "comment" when comment is created.
Do you please know, what could be wrong? Bellow are two ways how I tried to create db, but none has made connections with ForeingKey.
Tryed using Pragma to force foreignkey, but it didnt help. Tried to enforce ForeignKey on with sqlite> PRAGMA foreign_keys = ON; but it does not persist.
Here is my code:
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///userdata.db'
db = SQLAlchemy(app)
engine = create_engine('sqlite:///userdata.db')
def _fk_pragma_on_connect(dbapi_con, con_record):
dbapi_con.execute('pragma foreign_keys=ON')
from sqlalchemy import event
event.listen(engine, 'connect', _fk_pragma_on_connect)
class Post(db.Model):
__tablename__ = 'post'
id = db.Column(Integer, primary_key=True)
title = db.Column(String(50))
subtitle = db.Column(String(50))
author = db.Column(String(20))
date_posted = db.Column(DateTime)
content = db.Column(Text)
post_rel = relationship('Comment',
back_populates='comment_rel',
foreign_keys='[Comment.post_id]')
def get_comments(self):
return Comments.query.filter_by(
post_id=post.id).order_by(Comments.timestamp.desc())
def __repr__(self):
return '<Post %r>' % (self.body)
class Comment(db.Model):
__tablename__ = 'comment'
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(140))
author = db.Column(db.String(32))
timestamp = db.Column(db.DateTime(), default=datetime.utcnow, index=True)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
comment_rel = relationship('Post', uselist=False, back_populates='post_rel')
def __init__(self, text, author, timestamp):
""""""
self.text = text
self.author = author
self.timestamp = timestamp
def __repr__(self):
return '<Post %r>' % (self.body)
def show(self):
return self.author + '\n' + self.text
#app.route('/addcomment', methods=['POST'])
def addcomment():
commentar = request.form['commentar']
comment_done = Comment(text=commentar, author=current_user.username,
timestamp=datetime.now())
db.session.add(comment_done, 'PRAGMA foreign_keys=on')
db.session.commit()
return render_template('post.html', post=post)

Flask-SQLAlchemy not creating my tables

SQLAlchemy and for some reason when i run my create_db.py only the migration table is created.
I tried it from python terminal with from modules import db,models then running db.create_all() but it still gives the same result.
this is my models.py.
from __init__ import db
from datetime import datetime
class Batch(db.Model):
__tablename__='batch'
batch_id = db.Column(db.String, primary_key=True)
#total = db.Column(db.Integer)
success = db.Column(db.Integer)
failure = db.Column(db.Integer)
folder = db.Column(db.String(15))
email = db.Column(db.String(20))
detail = db.relationship('Conversion', backref='details',lazy='dynamic')
platform = db.relationship('Platform', backref='pub_data', lazy = 'dynamic')
def __init__(self,batch_id,success,failure,folder,email):
self.batch_id = batch_id
self.success = success
self.failure = failure
self.folder = folder
self.email = email
class Conversion(db.Model):
__tablename__ = 'conversion'
id = db.Column(db.Integer, primary_key=True)
batch_id = db.Column(db.String,db.ForeignKey('batch.batch_id'))
file_names = db.Column(db.String)
status = db.Column(db.String(6))
error = db.Column(db.Text)
res_prop = db.Column(db.Integer)
def __init__(self,batch_id,file_names,status,res_prop,error=None):
self.batch_id = batch_id
self.file_names = file_names
self.status = status
self.error = error
self.res_prop = res_prop
class Platform(db.Model):
__tablename__ = 'platform'
id= db.Column(db.Integer,primary_key=True)
batch_id = db.Column(db.String, db.ForeignKey('batch.batch_id'))
title = db.Column(db.String)
pub_date = db.Column(db.DateTime)
def __init__(self,batch_id,title):
self.batch_id = batch_id
self.title = title
self.pub_date = datetime()
And here is my create_db.py
from modules import models
from modules import db
from migrate.versioning import api
from modules.default_config import SQLALCHEMY_DATABASE_URI , SQLALCHEMY_MIGRATE_REPO
import os.path
db.create_all()
db.session.commit()
if not os.path.exists(SQLALCHEMY_MIGRATE_REPO):
api.create(SQLALCHEMY_MIGRATE_REPO, 'database repository')
api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
else:
api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, api.version(SQLALCHEMY_MIGRATE_REPO))
on changing
from __init__ import db
to
from modules import db
in models.py it worked.
when running flask application from outside package one needs to import everything from the package itself and not the individual modules.

Flask-SQLAlchemy - Order shows by number of followers

I am trying to create a query which will return all shows in database ordered by number of users who have it as favorite.
Simplified working code:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.sql import func
import logging
app = Flask(__name__)
db = SQLAlchemy(app)
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
favorite_series = db.Table('favorite_series',
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('series_id', db.Integer, db.ForeignKey('series.id')))
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
favorite_series = db.relationship('Serie', secondary=favorite_series,
backref=db.backref('users', lazy='dynamic'))
def __repr__(self):
return '<User {0}>'.format(self.name)
class Serie(db.Model):
__tablename__ = 'series'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
def __repr__(self):
return '<Serie {0}>'.format(self.name)
u1 = User()
u1.name = 'user1'
u2 = User()
u2.name = 'user2'
u3 = User()
u3.name = 'user3'
s1 = Serie()
s1.name = 'Serie1'
s2 = Serie()
s2.name = 'Serie2'
s3 = Serie()
s3.name = 'Serie3'
s4 = Serie()
s4.name = 'Serie4'
s5 = Serie()
s5.name = 'Serie5'
u1.favorite_series.extend([s1, s3, s5])
u2.favorite_series.extend([s1, ])
u3.favorite_series.extend([s1, s2, s3])
u1.favorite_series.extend([s1, s2])
db.session.add(u1)
db.session.add(u2)
db.session.add(u3)
db.session.add(s1)
db.session.add(s2)
db.session.add(s3)
db.session.add(s4)
db.session.add(s5)
db.create_all()
db.session.commit()
And I try to retrieve them with:
shows = Serie.query.join(Serie.users).order_by(func.count(Serie.users)).all()
print shows
But this throws error in SQL syntax, I tried to search for something but could not come up with anything working.
Any help would be appreciated.
Working solution:
sub = db.session.query(favorite_series.c.series_id, func.count(favorite_series.c.user_id).label('count')).group_by(favorite_series.cā€Œā€‹.series_id).subquery()
shows = db.session.query(Serie, sub.c.count).outerjoin(sub, Serie.id == sub.c.series_id).order_by(db.desc('count')).all()

Categories

Resources