Let's say I have these models:
class User(db.Model):
__tablename__ = 'Users'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
alias = db.Column(db.String(120), index=True, unique=True)
name = db.Column(db.String(120), index=True, unique=False)
lastname = db.Column(db.String(120), index=True, nullable=False)
email = db.Column(db.String(120), index=True, nullable=False)
password = db.Column(db.String(120), index=False, nullable=True)
created_on = db.Column(db.DateTime, default=datetime.now)
updated_on = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
class A(db.Model):
__tablename__ = 'A'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True)
class B(db.Model):
__tablename__ = 'B'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True)
I want to create another model called Audit that can referentiate A and B, so I was thinking about polymorphic associations, but I could not find a valid documentation to do that.
class Audit(db.Model):
__tablename__ = 'audit'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True)
user_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=True)
object???
I want to have an object that can point to A or B.
I'm just going to guess that maybe you want something like below. I find that sometimes just columns that are conditionally set is more useful unless you really have an inheritance tree, ie. truly polymorphic models.
class Audit(db.Model):
__tablename__ = 'audit'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True)
user_id = db.Column(db.Integer, db.ForeignKey('Users.id'), nullable=True)
dataset_id = db.Column(db.Integer, db.ForeignKey('dataset.id'), nullable=True)
dataset = db.relationship('Dataset', backref='audits')
class Dataset(Base):
__tablename__ = 'datasets'
id = Column(Integer, primary_key=True)
type = Column(String(20))
name = db.Column(db.String(120), index=True, unique=True)
__mapper_args__ = {
'polymorphic_on':type,
# You can probably use None here
# and set type to nullable= False
# if you don't want a base case
'polymorphic_identity': 'c'
}
class DatasetA(Dataset):
info = db.Column(db.String(120))
__mapper_args__ = {
'polymorphic_identity':'a'
}
class DatasetB(Dataset):
__mapper_args__ = {
'polymorphic_identity':'b'
}
Related
I have these three model. One user have multiple roles.I am stuck for get roles of user.
How can I get the user with roles using strawberry dataloader?
class UserRole(Base):
__tablename__ = "user_roles"
id = Column(Integer, primary_key=True, index=True)
user = Column(Integer, ForeignKey("users.id"))
role = Column(Integer, ForeignKey("roles.id"))
created_at = Column(DateTime(), server_default=func.now())
updated_at = Column(DateTime(), nullable=True)
class Role(Base):
__tablename__ = "roles"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(255), unique=True, index=True, default="patient")
description = Column(String(255), nullable=True)
created_at = Column(DateTime(), server_default=func.now())
updated_at = Column(DateTime(), nullable=True)
def __repr__(self):
return f"{self.name}"
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
first_name = Column(String(255), nullable=True)
last_name = Column(String(255), nullable=True)
email = Column(String(255), unique=True, index=True)
roles = relationship(
"Role",
secondary="user_roles",
backref=backref("users", lazy="dynamic"),
)
created_at = Column(DateTime(), server_default=func.now())
updated_at = Column(DateTime(), nullable=True)
def __repr__(self):
return f"{self.email}"
Now I am using this tutorial https://strawberry.rocks/docs/guides/dataloaders
I'm trying to create a one to many relationship between two tables and I am having some issues with that.
Tables code
class Movies(db.Model):
__tablename__ = 'movies'
id = db.Column(db.String(300), primary_key=True)
cat_id = db.relationship('Category', backref='movie')
title = db.Column(db.String(250), nullable=False)
link = db.Column(db.String(250), nullable=False)
duration = db.Column(db.String(250), nullable=False)
thumb_large = db.Column(db.String(250), nullable=False)
thumb = db.Column(db.String(250), nullable=False)
embed = db.Column(db.String(250), nullable=False)
tags = db.Column(db.String(250), nullable=False)
published = db.Column(db.String(250), nullable=False)
class Category(db.Model):
__tablename__ = 'category'
id = db.Column(db.String(300), db.ForeignKey('movies.cat_id'), primary_key=True)
category = db.Column(db.String(30), nullable=False)
I'm trying to migrate it but it give me this error sqlalchemy.exc.NoReferencedColumnError: Could not initialize target column for ForeignKey 'movies.cat_id' on table 'category': table 'movies' has no column named 'cat_id'
I can't understand why this is happening if I already set the relationship.
Any idea what should I do?
I think that should fix it.
In my opinion the documentation of SQLAlchemy regarding relationships is very helpful. You can find this here.
class Movie(Model):
__tablename__ = 'movies'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(255), nullable=False, unique=True, index=True)
link = db.Column(db.String(255), nullable=False)
duration = db.Column(db.String(255), nullable=False)
thumb_large = db.Column(db.String(255), nullable=False)
thumb = db.Column(db.String(255), nullable=False)
embed = db.Column(db.String(255), nullable=False)
tags = db.Column(db.String(255), nullable=False)
published = db.Column(db.String(255), nullable=False)
cat_id = db.Column(db.Integer, ForeignKey('categories.id'))
category = db.relationship('Category', backref='movies')
class Category(Model):
__tablename__ = 'categories'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(31), nullable=False, unique=True, index=True)
Here is my clinic relationship between the patient and patient-detail, this might help you, and it does work for me.
class Patient(db.Model, UserMixin):
__bind_key__ = 'patient'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(10), nullable=False)
number = db.Column(db.String(11), unique=False, nullable=False)
gender = db.Column(db.String(10), nullable=False)
birth = db.Column(db.String(20), nullable=False)
IDcard = db.Column(db.String(12), nullable=False)
age = db.Column(db.String(3), unique=False, nullable=False)
create = db.Column(db.DateTime, nullable=False, default=datetime.now)
details = db.relationship('Detail', backref='patient', lazy=True)
class Detail(db.Model, UserMixin):
__bind_key__ = 'detail'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=False, nullable=False)
Symptom = db.Column(db.String(100), nullable=False)
Initial_diagnosis = db.Column(db.String(50), nullable=False)
Preliminary_treatment_plan = db.Column(db.String(100), nullable=False)
Check_result = db.Column(db.String(50), nullable=False)
Patient_reason = db.Column(db.String(100), unique=False, nullable=False)
Doctor_name = db.Column(db.String(20), unique=False, nullable=False)
Date_of_diagnosis = db.Column(db.DateTime, nullable=False, default=datetime.now)
detail = db.Column(db.Integer, db.ForeignKey('patient.id'), nullable=False)
date_add = db.Column(db.DateTime, nullable=False, default=datetime.now)
I have these two models:
class User(db.Model, UserMixin):
__tablename__ = 'users'
__table_args__ = (
PrimaryKeyConstraint('id',),
)
id = db.Column(db.Integer, primarky_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
class Review(db.Model):
__tablename__ = 'reviews'
__table_args__ = (
PrimaryKeyConstraint('id', ),
)
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
I wanted to create a relationship between these two tables so that when a user writes a review it should go to Review model and it has a relation with user_id in Users model. I have tried lots of answers but they are returning different kinds of errors I am confused, can anybody help?
You can use db.relationship to create a one-to-many relationship between users and reviews.
class User(db.Model, UserMixin):
__tablename__ = 'users'
__table_args__ = (
PrimaryKeyConstraint('id',),
)
id = db.Column(db.Integer, primarky_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
reviews = db.relationship('Review', backref='user', cascade='all, delete, delete-orphan')
class Review(db.Model):
__tablename__ = 'reviews'
__table_args__ = (
PrimaryKeyConstraint('id', ),
)
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
This would allow for user.reviews and review.user
Try this:
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
user = db.relationship(User, backref='user_reviews', lazy=True)
And read the documentation.
I am building a online quiz app where both teacher and students can login. Teachers can create quizzes and students can run those quizzes. How can I attach both Teacher and Student model with User model so that properties like Teacher_Name or Student_Class etc can be accessed via current_user?
This is not a problem regarding user role. Because using flask-security I can do that pretty easily but providing role means grouping users by their access level but not actually identifying them. I mean if a student logs in I need know who is this particular student represented by the current logged in user. Only then I can store his/her result with his/her record.
Followings are my sqlalchemy models...
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
class Student(db.Model):
__tablename__ = 'student'
id = db.Column(db.Integer, primary_key=True)
cls = db.Column(db.String(4), nullable=False, default='V')
sec = db.Column(db.String(1), nullable=False, default='A')
roll = db.Column(db.Integer, nullable=False, default=1)
name = db.Column(db.String(24), nullable=False)
dob = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
sex = db.Column(db.Enum(Gender), nullable=False, default=Gender.male)
results = db.relationship('Result', backref='student', lazy=True)
__table_args__ = (db.UniqueConstraint("cls", "roll", name="cls_roll"),)
class Teacher(db.Model):
__tablename__ = 'teacher'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(24), nullable=False)
subject = db.Column(db.String(4), nullable=False)
quiz_ques = db.Table('quiz_ques', db.Column('quiz_id', db.Integer, db.ForeignKey('quiz.id'), nullable=False),
db.Column('mcq_id', db.Integer, db.ForeignKey('mcq.id'), nullable=False),
db.PrimaryKeyConstraint('quiz_id', 'mcq_id'))
class Quiz(db.Model):
__tablename__ = 'quiz'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), nullable=False, unique=True)
subject = db.Column(db.String(4), nullable=False)
marks = db.Column(db.Integer, nullable=False, default=1)
time_limit = db.Column(db.Integer, nullable=False, default=20)
questions = db.relationship('MCQ', secondary=quiz_ques, lazy='subquery', backref=db.backref('quizzes', lazy=True))
results = db.relationship('Result', backref='quiz', lazy=True)
class MCQ(db.Model):
__tablename__ = 'mcq'
id = db.Column(db.Integer, primary_key=True)
subject = db.Column(db.String(4), nullable=False)
topic = db.Column(db.String(150), nullable=False)
question = db.Column(db.String(255), nullable=False)
answers = db.Column(db.Text(), nullable=False)
class Result(db.Model):
__tablename__ = 'result'
id = db.Column(db.Integer, primary_key=True)
date_created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
marks_obtained = db.Column(db.Integer, nullable=False, default=0)
response = db.Column(db.Text(), nullable=True)
stud_id = db.Column(db.Integer, db.ForeignKey('student.id'), nullable=False)
quiz_id = db.Column(db.Integer, db.ForeignKey('quiz.id'), nullable=False)
The code should allow me to do something like this -
current_user.student.name = 'John Doe'
or
current_user.teacher.subject = 'Math'
I do have these 2 calsses als DB models trying to buidl a 1 to many relation:
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), index=True) #, unique=True)
firstname = db.Column(db.String(50))
lastname = db.Column(db.String(50))
bt_ids = db.relationship("BT", order_by="BT.id", backref="user")
class BT(db.Model):
__tablename__ = 'bt'
id = db.Column(db.Integer, primary_key=True)
bt_id = db.Column(db.String(255), unique=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship("User", backref=db.backref('bt', order_by=id))
But I guess I do not really understand the way of setting up the relationships:
ArgumentError: Error creating backref 'user' on relationship 'User.bt_ids': property of that name exists on mapper 'Mapper|BT|bt'
Any ideas?
EDIT
I actually wanted to achive something like the example of SQLAlchemy
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(12))
**addresses = relationship("Address", order_by="Address.id", backref="user")**
def __repr__(self):
return "<User(name='%s', fullname='%s', password='%s')>" % (
self.name, self.fullname, self.password)
class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
**user = relationship("User", backref=backref('addresses', order_by=id))**
def __repr__(self):
return "<Address(email_address='%s')>" % self.email_address
There is already a FK relation between User and BT through user_id property so you can't create another relation named user in BT.
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), index=True) #, unique=True)
firstname = db.Column(db.String(50))
lastname = db.Column(db.String(50))
bts = db.relationship("BT", order_by="BT.id", backref="user")
class BT(db.Model):
__tablename__ = 'bt'
id = db.Column(db.Integer, primary_key=True)
bt_id = db.Column(db.String(255), unique=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
Now I got it...
This was wrong:
user = db.relationship("User", backref=db.backref('bt_ids', order_by=id))
Now it works!