Reputation: 301
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)
Upvotes: 2
Views: 6500
Reputation: 160
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
Upvotes: 3
Reputation: 12018
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
Upvotes: 0