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.
Related
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?
I'm trying to set up a one-to-many relation between two tables (User and BlogPost, respectively).
I tried copying what the course(?) solution for this and still get foreign-key errors. What do I have wrong? Or, is this actually an issue with sqlalchemy (v. 1.3.19)?
I've even tried upgrading to the current version (1.4.31) with no success. I was getting run-time errors (flask page error reports) usually around the posts = BlogPost.query.all() line in home(). Now that I've upgraded the package, I'm getting a build-time error (AttributeError: can't set attribute) stemming from the db.create_all() line.
I've also tried deleting the db, again with no success.
Please leave a comment if this was answered somewhere else or if more info is needed.
Here's a snippet from Main.py:
db = SQLAlchemy(app)
class User(db.Model, UserMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(250), nullable=False)
password = db.Column(db.String(250), nullable=False)
name = db.Column(db.String(100), nullable=False)
posts = relationship("BlogPost", back_populates="author")
class BlogPost(db.Model):
__tablename__ = "blog_posts"
id = db.Column(db.Integer, primary_key=True)
author_id = db.Column(db.Integer, db.ForeignKey("users.id"))
title = db.Column(db.String(250), unique=True, nullable=False)
subtitle = db.Column(db.String(250), nullable=False)
date = db.Column(db.String(250), nullable=False)
body = db.Column(db.Text, nullable=False)
img_url = db.Column(db.String(250), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey("users.id"))
author = relationship("User", back_populates="posts")
db.create_all()
#app.route('/')
def home():
posts = BlogPost.query.all()
user = current_user
return render_template("index.html", all_posts=posts, user=user)
I still don't know what's wrong, but the following code works in a newer project. Like I said in one of the comments: I suspect that there's an issue with my current PyCharm project.
db = SQLAlchemy(app)
class User(UserMixin, db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(100))
posts = relationship("BlogPost", back_populates="author")
class BlogPost(db.Model):
__tablename__ = "blog_posts"
id = db.Column(db.Integer, primary_key=True)
author_id = db.Column(db.Integer, db.ForeignKey("users.id"))
author = relationship("User", back_populates="posts")
title = db.Column(db.String(250), unique=True, nullable=False)
subtitle = db.Column(db.String(250), nullable=False)
date = db.Column(db.String(250), nullable=False)
body = db.Column(db.Text, nullable=False)
img_url = db.Column(db.String(250), nullable=False)
db.create_all()
#app.route('/')
def home():
posts = BlogPost.query.all()
return render_template("index.html", all_posts=posts)
I am beginner trying to make a relational database in Flask project using SQLalchemy
This is the error that I am getting when I try to register a user:-
sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Question->question, expression 'Answer' failed to locate a name ('Answer'). If this is a class name, consider adding this relationship() to the <class 'nothingness.models.Question'> class after both dependent classes have been defined.
DB relationships are:-
User (Many to Many) Table
User (1 to Many) Question
Question (1 to Many) Answer
Table (1 to Many) Question
Here are my codes
from datetime import datetime
from nothingness import db
members = db.Table(
"member",
db.Column("id", db.Integer, primary_key=True),
db.Column("table_id", db.Integer, db.ForeignKey("table.id")),
db.Column("user_id", db.Integer, db.ForeignKey("user.id")),
)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(25), unique=True, nullable=False)
name = db.Column(db.String(25), nullable=False)
email = db.Column(db.String(), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default="default.jpg")
password = db.Column(db.String(60), nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
member = db.relationship("Table", secondary=members, backref=db.backref("members", lazy=True))
prashna = db.relationship("Question", backref="user", lazy=True)
def __repr__(self):
return f"User('{self.name}', '{self.username}', '{self.email}', '{self.image_file}')db.Model"
class Table(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(25), nullable=False)
key = db.Column(db.String(5), nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
question = db.relationship("Question", backref="questions", lazy=True)
def __repr__(self):
return f"Table('{self.id}', '{self.name}', '{self.key}', {self.created_at})"
class Question(db.Model):
id = db.Column(db.Integer, primary_key=True)
question = db.Column(db.String(255), nullable=False)
asked_by = db.Column(db.Integer, db.ForeignKey("user.id"))
asked_to = db.Column(db.Integer, nullable=False)
answer = db.relationship("Answer", backref="question", lazy=True)
table = db.Column(db.Integer, db.ForeignKey("table.id"))
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
class Answer:
id = db.Column(db.Integer, primary_key=True)
points = db.Column(db.Integer)
answer = db.Column(db.String(255), nullable=False)
answered_by = db.Column(db.Integer, nullable=False)
table_id = db.Column(db.Integer, nullable=False)
created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
question = db.Column(db.Integer, db.ForeignKey("question.id"))
def __repr__(self):
return f"Answer('{self.points}', '{self.answer}', '{self.created_at}')"
This error occurred because I forgot to subclass Answer with db.Model
I am new using sqlAlchemy and having problem creating new tables, specially when it comes around 2 foreign keys pointing to 1 table:
class Offers(db.Model):
__tablename__ = 'offers'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
contact_ign = db.Column(db.String(100))
conversion_rate = db.Column(db.Float)
stock = db.Column(db.Integer)
create_date = db.Column(db.DateTime(timezone=True), default=func.now())
currency_pair = db.relationship('CurrencyPairs', backref='pair', lazy='dynamic')
class CurrencyPairs(db.Model):
__tablename__ = 'currency_pairs'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
league = db.Column(db.String(100))
pair_id = db.Column(db.Integer, db.ForeignKey('offers.id'))
want = db.relationship('Currency', backref='want', lazy='dynamic')
have = db.relationship('Currency', backref='have', lazy='dynamic')
class Currency(db.Model):
__tablename__ = 'currency'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
poe_trade = db.Column(db.Integer, nullable=False)
poe_official = db.Column(db.String(10), nullable=False)
tier = db.Column(db.Integer, nullable=False)
want_id = db.Column(db.Integer, db.ForeignKey('currency_pairs.id'))
have_id = db.Column(db.Integer, db.ForeignKey('currency_pairs.id'))
The error I am getting is:
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'Mapper|CurrencyPairs|currency_pairs'. Original exception was: Could not determine join condition b
etween parent/child tables on relationship CurrencyPairs.want - there are multiple foreign key paths linking the tables. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key refe
rence to the parent table
I have try different things but I get same result.
What am I doing wrong?
Thanks In advance.
I know this is an old question, but I had the same problem. I hope to help others with the answer.
This issue is addressed in the sqlalchemy documentation.
https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#handling-multiple-join-paths
class Offers(db.Model):
__tablename__ = 'offers'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
contact_ign = db.Column(db.String(100))
conversion_rate = db.Column(db.Float)
stock = db.Column(db.Integer)
create_date = db.Column(db.DateTime(timezone=True), default=func.now())
currency_pair = db.relationship('CurrencyPairs', backref='pair', lazy='dynamic')
class CurrencyPairs(db.Model):
__tablename__ = 'currency_pairs'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
league = db.Column(db.String(100))
pair_id = db.Column(db.Integer, db.ForeignKey('offers.id'))
want_currency = relationship("Currency", foreign_keys='[Currency.want_id]', back_populates="want_currency_pairs")
have_currency = relationship("Currency", foreign_keys='[Currency.have_id]', back_populates="have_currency_pairs")
class Currency(db.Model):
__tablename__ = 'currency'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
poe_trade = db.Column(db.Integer, nullable=False)
poe_official = db.Column(db.String(10), nullable=False)
tier = db.Column(db.Integer, nullable=False)
want_currency_pairs = relationship(CurrencyPairs, foreign_keys="[Currency.want_id]", back_populates="want_currency")
have_currency_pairs = relationship(CurrencyPairs, foreign_keys="[Currency.have_id]", back_populates="have_currency")
The way you wrote the code, sqlalchemy can't really understand which relationship to choose, because you have 2 of the same relationship. So you have to describe to sqlalchemy that there are 2 relationships to the same table.
I have the following line of code in my models.py file:
referalls = db.table('referrals',
db.Column('referrer', db.String(64), db.ForeignKey('User.email')),
db.Column('referral', db.String(64), db.ForeignKey('User.email'))
)
This is to create a many-to-many relationship table for a referral system I'm trying to implement.
However, when I run my migrate/upgrade command, Alembic is not creating the table.
I'm following the official Flask-SQLAlchemy tutorial: http://flask-sqlalchemy.pocoo.org/2.1/models/
For clarity's sake, here's the User class:
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(64), unique=True, index=True)
username = db.Column(db.String(64), unique=True, index=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
password_hash = db.Column(db.String(128))
confirmed = db.Column(db.Boolean, default=False)
name = db.Column(db.String(64))
location = db.Column(db.String(64))
about_me = db.Column(db.Text())
member_since = db.Column(db.DateTime(), default=datetime.utcnow)
last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
...
I believe my problem might be the following line (pulled from the official Flask-SQLAlchemy documentation):
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('pages', lazy='dynamic'))
I tried:
referalls = db.relationship('User', secondary=referalls,
backref=db.backref('users', lazy='dynamic'))
But same thing: Alembic's not identifying the referrals table.
Any input on this is greatly appreciated.
I had the same problem and solved by using a class inheriting db.Model instead of declaring a table the way the flask tutorial suggests. When I defined everything as a class it just worked.
Possibly its a problem with alembic.
Try:
class Referalls(db.Model):
__tablename__ = 'referalls'
referrer = db.Column(db.String(64), db.ForeignKey('User.email'))
referral = db.Column(db.String(64), db.ForeignKey('User.email'))