1
votes

I have a Flask-SQLAlchemy association table named 'followers' and when I run the query following query via REPL it runs fine, but when running the code on the Flask application it gives me the error "'AttributeError: 'function' object has no attribute 'c'".

Function calling the query

@app.route('/following/<int:user_id>', methods=['GET'])
@login_required
def following(user_id):
    """
    Show all the Tutors the user is following
    """

    user = Users.query.get(user_id)
    
    page = request.args.get('page', 1, type=int)

    result = db.session.query(Users, Tutors)\
        .join(Tutors, Tutors.user_id==Users.id ,full=True)\
        .join(followers, Tutors.id == followers.c.followed_id)\
        .filter(user_id==followers.c.follower_id).all()
    
    next_url = url_for('index', page=result.next_num) if result.has_next else None
    prev_url = url_for('index', page=result.prev_num) if result.has_prev else None

    data = {}
    data['user'] = []
    data['tutor'] = []
    rows = len(result.items)

    for i in range(rows):
        data['user'].append(result.items[i][0])
        data['tutor'].append(result.items[i][1])

    return render_template('index.html', title='Following', 
                        data=data, rows=rows,
                        next_url=next_url, prev_url=prev_url)

Just the query

    result = db.session.query(Users, Tutors)\
        .join(Tutors, Tutors.user_id==Users.id ,full=True)\
        .join(followers, Tutors.id == followers.c.followed_id)\
        .filter(user_id==followers.c.follower_id).all()

Models

followers = db.Table('followers',
    db.Column('follower_id', db.Integer, db.ForeignKey('users.id')),
    db.Column('followed_id', db.Integer, db.ForeignKey('tutors.id'))
)

class Users(UserMixin, db.Model):
    __tablename__ = 'users'
    __table_args__ = {'extend_existing': True}
    id = db.Column(db.Integer, primary_key=True)

    ... (other non-related properties)

    followed = db.relationship('Tutors', secondary=followers, lazy='dynamic',
        backref=db.backref('followers', lazy='dynamic'))

class Tutors(db.Model):
    __tablename__ = 'tutors'
    __table_args__ = {'extend_existing': True}
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    ... (other non-related properties)

Error traceback

Error on request:
Traceback (most recent call last):
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/werkzeug/serving.py", line 323, in run_wsgi
    execute(self.server.app)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/werkzeug/serving.py", line 312, in execute
    application_iter = app(environ, start_response)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 2464, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app
    response = self.handle_exception(e)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/env/lib/python3.8/site-packages/flask_login/utils.py", line 272, in decorated_view
    return func(*args, **kwargs)
  File "/Users/richardnienkotter/Documents/Projects/codetutors/app/routes.py", line 134, in following
    result = db.session.query(Users, Tutors, followers.c.follower_id, followers.c.followed_id)\
AttributeError: 'function' object has no attribute 'c'

Using type() on the Debug Console shows that 'followers' is a function and that's the root of the problem, but why is it being called as a function?

Solution

In routes.py I had the same name for both the view function and the association table, which was causing the problem.

Thanks Abhi for the help :)

1
You've rebound followers to a function at some point. - Ilja Everilä

1 Answers

1
votes

please check the file named "/Users/richardnienkotter/Documents/Projects/codetutors/app/routes.py", line 134, in following

There may be a function named as followers, which is contradicting with your table named as followers.