1

I'm working through Miguel Grinberg's Flask book.

In chapter 12, he has you define an association object Follow with followers and the followed, both mapping to a user, as well as adding followers and followed to the Users class.

I originally put the association table after the User table, and got an error when I ran python manage.py db upgrade:

line 75, in User followed = db.relationship('Follow', foreign_keys=  [Follow.follower_id], 
NameError: name 'Follow' is not defined

Then I moved the association object class Follow above the class User definition, and re-ran the migration. This time it worked.

Can someone explain the reason for this?

Both class definitions seem to need the other.

Is order something I should know about flask-sqlalchemy specifically, sqlalchemy, or ORM in general?

The SQLAlchemy documentation says "we can define the association_table at a later point, as long as it’s available to the callable after all module initialization is complete" and the relationship is defined in the class itself.

That is, for the case you're using and association_table to show the relationship between two separate models. I didn't see anything about this case in the Flask-SQLAlchemy or SQLAlchemy documentation, but it's very possible I just didn't recognize the answer when I saw it.

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    ...
    followed = db.relationship('Follow',
                           foreign_keys=[Follow.follower_id],
                           backref=db.backref('follower', lazy='joined'),
                           lazy='dynamic',
                           cascade='all, delete-orphan')
    followers = db.relationship('Follow',
                            foreign_keys=[Follow.followed_id],
                            backref=db.backref('followed', lazy='joined'),
                            lazy='dynamic',
                            cascade='all, delete-orphan')

Order of definition with:

class Follow(db.Model):
    __tablename__ = 'follows'
    follower_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    followed_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow)

Or maybe order doesn't matter at all, and I am misattributing a problem?

1 Answer 1

1

First of all if you are going to use some class in later it must be defined already. The defination order is important, you can not use a class which doesn't exist yet.

Second, sqlalchemy says you will defined a third table to create relationship. If you use this approach User and Follow class would not access each other attributes so it won't cause defination order error.

Finally, if you won't define an associate table then you have to put classes in right order, to use attributes of them.

Sign up to request clarification or add additional context in comments.

2 Comments

Follow is the association object (I'm not using an association table because the relationship is from User to User). Each is a class, each references the other, so no matter which goes first it's circular.
Then move Follow class before User class it will work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.