2

I've been using flask with flask-sqlalchemy successfully for a number of weeks, but all of a sudden my code is coming up with this error: AttributeError: 'function' object has no attribute 'query', relating to this line of code: project_choices = [(str(c.id) + ': ' + c.project_name) for c in Projects.query.all()]

Seems like the flask-sqalchemy Projects class is not being successfully created but I can't work out why.

Main routes file:

from flask import Flask, request, flash, url_for, redirect, render_template, session
from flask_sqlalchemy import SQLAlchemy
from app import db
from app import app
from app.forms import Basic_data_Form, Which_project#, Areas_form
from flask_bootstrap import Bootstrap
from app.models import Projects

@app.route('/Index', methods = ['GET', 'POST'])
def Index():

   if 'project_name' not in session:
      session['project_name'] = "0: No project selected"

   project_name = session['project_name'].split(':')[1]

   project_choices = [(str(c.id) + ': ' + c.project_name) for c in Projects.query.all()]  
   form2 = Which_project()
   form2.project_choice.choices = project_choices
   
   return render_template('Index.html', form2=form2, projects = Projects.query.filter_by(id=session['project_name'].split(':')[0]).all(), project_name=project_name)

init file:

from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap

app = Flask(__name__)
app.config.from_object(Config)

db = SQLAlchemy(app)

bootstrap = Bootstrap(app)

from app import routes

models file:

from app import db

class Projects(db.Model):
   id = db.Column(db.Integer, primary_key=True, autoincrement=True)
   project_name = db.Column(db.String(100))
   user_id = db.Column(db.String(100))
   address = db.Column(db.String(100))
   region = db.Column(db.String(100)) 
   postcode = db.Column(db.String(20))
   building_year = db.Column(db.Integer)
   climate_file = db.Column(db.String(100))
   building_TFA = db.Column(db.Float)
   thermal_mass = db.Column(db.String(100))
   winter_int_temp = db.Column(db.Float)
   summer_int_temp = db.Column(db.Float)
   height_above_sea = db.Column(db.Float)
   occupany = db.Column(db.Float)

   def __repr__(self):
        return '<Project {}>'.format(self.project_name)
3
  • just check in flask shell, are you able to do Projects query or not ? Commented Dec 17, 2020 at 10:30
  • That's the weird thing. I can do a Project.query.all() command in the shell and Projects shows up. But it doesn't seem to want to show up when running the script. Commented Dec 17, 2020 at 18:50
  • (app) samarcher201135@penguin:~/microblog$ flask shell Python 3.7.3 (default, Jul 25 2020, 13:03:44) [GCC 8.3.0] on linux App: app [production] Instance: /home/samarcher201135/microblog/instance >>> from app import db >>> from app.models import Projects >>> Projects.query.all() [] >>> Commented Dec 17, 2020 at 19:34

2 Answers 2

3

I had a similar issue with that same error. It was because there was a function with the same name. So that is probably why it was saying a function had no attribute query even though the table used with sqlalchemy is a class

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

Comments

0

Consider either implementing a class function which renders the object into the current string representation you desire or implementing a hybrid property.

String method:

class Projects(db.Model):
    ...
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    project_name = db.Column(db.String(100))
    ...

    def __str__(self):
         return f'{self.id}: {self.project_name}'

Use string method as follows:

project_choices = Projects.query.all()  
form2 = Which_project()
# probably str(x) would work, but if it doesn't the code below def works
form2.project_choice.choices = [x.__str__() for x in project_choices]

Hybrid property method:

from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
class Projects(db.Model):
    ...
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    project_name = db.Column(db.String(100))
    ...

    @hybrid_property
    def project_choice(self):
        return f'{self.id}: {self.project_name}'

Use hybrid property as follows:

# Access only the hybrid property
project_choices = Projects.query(Projects.project_choice).all()  
form2 = Which_project()
form2.project_choice.choices = project_choices

8 Comments

Thanks for these suggestions. They all retain the .query method which is what's failing. I tried the str method, but still got the error:
File "/home/samarcher201135/microblog/app/routes.py", line 59, in Index project_choices = Projects.query.all() AttributeError: 'function' object has no attribute 'query'
Hm... Can you verify that Projects is being imported correctly? Are there any other objects with the same name elsewhere?
Additionally, what is the value of print(type(Projects)) when placed in the app main ? @SamArcher
just changed the name of the class to some random name, and suddenly it worked!!! Thanks for your suggestion. Seems like it must have got confused with some other 'Projects" object...
|

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.