I am using Postgresql and FlaskSqlalchemy . I want to create a relation such that a team can have multiple channels but a channel can only have one team(one-to-many relation). I have tried to do it by a one-to-many relationship as shown below I have the following code in models.py
class Team(db.Model):
__tablename__ = "team"
id = db.Column(db.Integer, primary_key=True)
team_owner_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False)
team_name = db.Column(db.String(50), nullable=False, unique=True)
team_logo = db.Column(db.String(120), default='default.png')
team_description = db.Column(db.String(110), default="Welcome to My team.....")
team_members = db.Column(MutableDict.as_mutable(JSON))
team_members_count = db.Column(db.Integer)
channel_list = db.relationship("Channel", backref="list", lazy=True)
class Channel(db.Model):
channel_id = db.Column(db.Integer, primary_key=True)
team_id = db.Column(db.Integer, db.ForeignKey("team.id"), nullable=False)
channel_name = db.Column(db.String(50), nullable=False, unique=True)
channel_logo = db.Column(db.String(120), default='default.jpg')
channel_description = db.Column(db.String(110), default="Welcome to My Channel.....")
channel_members = db.Column(MutableDict.as_mutable(JSON))
channel_members_count = db.Column(db.Integer)
I am able to create a team, but when I try to create a channel every thing goes fine except the relationship part . I have tried to make the channels_list(backref='list') a list by doing
list = []
Further code is given below
channel = Channel(channel_name=form.channel_name.data, channel_description =
form.channel_description.data , channel_members = {'member_id': [] , 'name' : []},
channel_members_count=channel_members_count, list = []
)
channel.list.append(form.channel_name.data)
db.session.add(channel)
db.session.commit()
NOTE: I have not added some code that is not relevant to this error eg populating channel_members to avoid wasting your time Now when I try to create channel I get the error:
AttributeError: 'dict' object has no attribute '_sa_instance_state'
TraceBack:[https://i.stack.imgur.com/2XHnl.png[1] Where am I making a fault or is it even possible to store a list while having a one-to-many relationship. Also it will be best if I can have a JSON object stored while maintaing this relation. Appreciate Your Guidance
CodePudding user response:
So what "backref" means is its a "back reference" to the parent "team" that a given channel is associated with.
So if for example you had an existing team called "team_a" in the database and you wanted to create a new channel that would be associated with this "team_a". Here's how you'd do it:
new_channel = Channel(channel_info)
# find team with name "team_a"
team = Team.query.filter_by(name="team_a").first()
# associate this team with the new_channel using the backref to the team
# which is called "list"
new_channel.list = team
db.session.add(new_channel)
db.session.commit()
Channel.list
is not a list its a reference to the team object that the given channel is related to. So you should use it to associate a channel with a team when you're creating a new channel. That way the channel will be indexed as part of the children (or the 'many') of the parent team. Since there is a one-to-many from team -> channel.
This makes it so we can get all channels associated with the team using the "channel_list" property on a "team" object. You don't need to append to it directly on the teams object, so long as you've associated the team with the channel while creating it.
I'd advice you to name the backref as something less confusing on the "teams" table to something like "team" or "parent_team". Like this:
channel_list = db.relationship("Channel", backref="team", lazy=True)