Multiple relationships to the same SQLAlchemy model - python

I have a User table that has role column. role can be student, professor or admin. User table have relation with Course table.
If relationship is between Course and student it should be many to many relation but if relationship is between Course and professor it should be one to many.
How to define multi relationship between two table with different roles?
User Model
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(40))
lastname = db.Column(db.String(40))
username = db.Column(db.String(40), nullable=False, unique=True)
password_hash = db.Column(db.String(100), nullable=False)
role = db.Column(db.SmallInteger, nullable=False, default=0)
create_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)
update_at = db.Column(db.DateTime, default=datetime.datetime.utcnow)
# what should i write instead of bellow lines?
# courses = db.relationship('Course', secondary=student_course, backref='students', lazy='dynamic')
# OR
# courses = db.relationship('Course', backref='teacher', lazy='dynamic')
ROLE_STUDENT = 0
ROLE_PROFESSOR = 1
ROLE_ADMIN = 2
Course Model
class Course(db.Model):
id = db.Column(db.Integer, primary_key=True)
teacher_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
title = db.Column(db.String(120))

Related

Querying user specific data in flask

I'm building an app that shows a database of different plant species. Each user sees the same table of plant species except for the "notes" column, which each user can edit to their own liking. This is the database structure I have created:
class Note(db.Model):
__tablename__ = 'plantdatabasenote'
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text(), nullable=False)
plant_id = db.Column(db.Integer, db.ForeignKey("plant.id"))
user_id = db.Column(db.Integer, db.ForeignKey("profile.id"))
class Plant(db.Model):
__tablename__ = 'plant'
id = db.Column(db.Integer, primary_key=True)
common_name = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
notes = db.relationship("Note", backref="user_notes")
class Profile(db.Model):
__tablename__ = 'profile'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(200), unique=True, nullable=False)
I tried to retrieve the notes of user 1 with the following:
Plant.query.filter(Plant.notes.any(user_id=1)).all()
Unfortunately, this does not give me all the plants with the notes of user 1. Any idea how to fix this?

Sqlite3 relational database

I am trying to connect the id in the user class to the user_id in task class. I read the documentation from sqlalchemy and I have a hard time understanding the db.relationship part. I have also encountered a problem when updating the tables, when I ran db.create_all() in the terminal, these classes wasn't updated (it previously worked). Is this because the relational database I set up was wrong?
Here is my classes
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
password = db.Column(db.String(80), nullable=False)
class Task(db.Model):
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
description = db.Column(db.Text)
complete =db.Column(db.Boolean, default=False)
And here is the documentation example
class Category(db.Model, CRUDMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
# Post table (in app/models/post.py)
class Post(db.Model, CRUDMixin):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
pub_date = db.Column(db.DateTime, default=datetime.utcnow)
# One to many relationship
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
category = db.relationship('Category', backref=db.backref('posts'))
Any answers or opinions will be greatly appreciated, thankyou.

how to use primary and foreign keys in SQL ALchemy

I have the following two tables. User and Project.
I need User_ID and name to be projected in Project table columns user_ID and User respectively but i couldn't achieve it.
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
User_ID = db.Column(db.Integer, unique=True)
name = db.Column(db.String(20))
project = db.relationship('Project', backref='proj')
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
user = db.Column(db.String(50), db.ForeignKey("user.name"))
UserID = db.Column(db.Integer, db.ForeignKey("user.User_ID"))
customer = db.Column(db.String(50))
lead_office = db.Column(db.String(50))
phase = db.Column(db.String(50))
Try this ( it worked for me in similar project):
class User(db.Model):
User_ID = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20))
class Project(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
id_user = db.Column(db.String(50), db.ForeignKey("User.User_ID"))
customer = db.Column(db.String(50))
lead_office = db.Column(db.String(50))
phase = db.Column(db.String(50))

How do i query table A and B,fetch a column from B and add it to the result ? Flask

I am trying to query two tables, Hostel and Room by joining them then fetch Hostel.name where my Room.hostel_id == Hostel.id so that my final query has Room data and a name from Hostel class, the Hostel.name.
Below are my classes
Hostel
class Hostel(UserMixin, db.Model):
__tablename__ = "hostel"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, index=True, unique=True)
location = db.Column(db.String(300), nullable=False)
management = db.Column(db.String(300), nullable=False)
rooms = db.Column(db.String(100), nullable=False)
caretaker = db.Column(db.String(300), nullable=False)
contact = db.Column(db.String(10), nullable=False)
description = db.Column(db.Text, nullable=False)
Room
class Room(UserMixin, db.Model):
__tablename__ = "room"
id = db.Column(db.Integer, primary_key=True)
rent = db.Column(db.Integer)
deposit = db.Column(db.Integer)
amenities = db.Column(db.String(300), nullable=False)
size= db.Column(db.String(300), nullable=False)
status = db.Column(db.String(300), nullable=False)
hostel_id = db.Column(db.Integer,nullable = False)
I have the following lines of code that I've tried working with;
room_data = Room.query\
.join(Hostel, Room.id==Hostel.id)\
.add_columns(Hostel.name)\
.filter(Room.hostel_id == Hostel.id)
and
room_data = Room.query.join(Hostel).filter(Room.hostel_id == Hostel.id).order_by(Room.id.desc()).all()
Help me fix this so that my query has all the details from the Room table and a new column that is from the hostel table that has the respective hostel name
Thanks, y'all. I simply added a relationship and used a backref to get the fields from the parent table
Added the following to my room table;
hostel_id = db.Column(db.Integer, db.ForeignKey("hostel.id"), nullable=False)
hostel = db.relationship("Hostel", backref=db.backref("hostel"), lazy=True)

Use Flask-SqlAlchemy to query relationship database

I'm trying to use Flask-SQLAlchemy to query out database for the user profile page
So far I don't have a solution for this problem, only able to query all the User data by using users.query.all()
Each user has their own role_id, department_id, researchfield_id.
How can i query out all the Role, Department, ResearchField data that has relationship with User through ID?
class User(UserMixin, db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
department_id = db.Column(db.Integer, db.ForeignKey('departments.id'))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
research_id = db.Column(db.Integer, db.ForeignKey('researchfields.id'))
class Department(db.Model):
__tablename__ = "departments"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(sqlalchemy.types.NVARCHAR(100), unique=True)
user = db.relationship('User', backref='department',
lazy='dynamic')
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(sqlalchemy.types.NVARCHAR(100), unique=True)
users = db.relationship('User', backref='role',
lazy='dynamic')
class ResearchField(db.Model):
__tablename__ = "researchfields"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(60), index=True)
parent_id = db.Column(db.Integer, db.ForeignKey("researchfields.id") , nullable=True)
users = db.relationship('User', backref='researchfield', lazy='dynamic')
If I understand correctly, what you're seeking for is a way to filter out users based on a specific model. Because in your example, the other way around is redundant - every user has only one department, so no need to filter out departments for that user. In order to achieve that, I would use the backref method provided by SQLAlchemy from the User model.
Here's an example consisting of two of the models:
from sqlalchemy.orm import backref
class User(UserMixin, db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
department_id = db.Column(db.Integer, db.ForeignKey('departments.id'))
department = db.relationship("Department", backref=backref("users", lazy="dynamic"))
class Department(db.Model):
__tablename__ = "departments"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(sqlalchemy.types.NVARCHAR(100), unique=True)
Now you can use:
department = Department.query.filter_by(id=1).first()
print(department.users.filter_by(is_admin=True).all()) # get all admins with that department
Every user has only one department, so you could just get the user's department by:
user = User.query.filter_by(id=1).first()
print(user.department) # prints Department object

Categories