简体   繁体   中英

Python flask_sqlalchemy: AttributeError: 'Table' object has no attribute 'added_by'

Here is my model class, which has definition of all database objects. (I've imported db object from another package which is an instance of sqlAlchemy())

from datetime import datetime
from TasMar import  db, login_manager
from flask import  current_app
from flask_login import UserMixin

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

class User(db.Model, UserMixin):
    __tablename__ = 'tm_user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20),unique=True, nullable=False)
    email = db.Column(db.String(120),unique=True, nullable=False)
    image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
    password=  db.Column(db.String(120), nullable=False)

    #foreign keys accessing this table's primary keys
    added = db.relationship('Tasks', lazy=True, foreign_keys='tm_task.added_by')
    assigned = db.relationship('Tasks', lazy=True, foreign_keys='tm_task.assigned_to')

    def __repr__(self):
            return "User('{}','{}','{}')".format(self.username,self.email,self.image_file)


class Tasks(db.Model):
    __tablename__ = 'tm_task'
    task_id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('tm_task.task_id'),nullable=True)
    descr = db.Column(db.String(500), nullable=False)
    added_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    added_by = db.Column(db.Integer, db.ForeignKey('tm_user.id'),nullable=False)
    assigned_to = db.Column(db.Integer, db.ForeignKey('tm_user.id'),nullable=False)
    last_updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    remark = db.Column(db.Text)


    parent = db.relationship('Tasks', remote_side=[task_id]) #self referential
    status = db.Column(db.Integer, db.ForeignKey('tm_status.id'),nullable=False)
    type = db.Column(db.Integer, db.ForeignKey('tm_type.id'),nullable=False)
    urgency = db.Column(db.Integer, db.ForeignKey('tm_urgency.id'),nullable=False)

    def __repr__(self):
            return "Tasks('{}','{}','{}','{}')".format(self.descr,self.added_on,self.added_by,self.assigned_to)

class tm_status(db.Model):
    __tablename__ = 'tm_status'
    id = db.Column(db.Integer, primary_key=True)
    status = db.Column(db.String(20),unique=True,nullable=False)
    status_f = db.relationship('Tasks', lazy=True, foreign_keys='tm_task.status')

    def __repr__(self):
            return "tm_status('{}')".format(self.status)

class tm_type(db.Model):
    __tablename__ = 'tm_type'
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(20),unique=True,nullable=False)
    type_f = db.relationship('Tasks', lazy=True, foreign_keys='tm_task.type')

    def __repr__(self):
            return "tm_type('{}')".format(self.type)

class tm_urgency(db.Model):
    __tablename__ = 'tm_urgency'
    id = db.Column(db.Integer, primary_key=True)
    urgency = db.Column(db.String(20),unique=True,nullable=False)
    urgency_f = db.relationship('Tasks', lazy=True, foreign_keys='tm_task.urgency')

    def __repr__(self):
            return "tm_urgency('{}')".format(self.urgency)

I use another class to create these objects and query data as following

from TasMar import db,create_app
from TasMar.models import User,Tasks,tm_status, tm_urgency,tm_type
app=create_app()
app.app_context().push()
#db.create_all()   #<<works perfectly but not below !
user = User.query.filter_by(email='dummy@email.com').first()
print(user)

create_all() works fine and it creates all the schema objects with correct relationship, however querying the data gives error. (ie running above code gives error as below) AttributeError: 'Table' object has no attribute 'added_by' Why am I getting this error?

Traceback (most recent call last):
  File "F:\My Documents\Official\work\EclipseWorkspace\TaMar\setup_db.py", line 7, in <module>
    user = User.query.filter_by(email='dummy@email.com').first()
  File "F:\Installations\Anaconda\lib\site-packages\flask_sqlalchemy\__init__.py", line 517, in __get__
    mapper = orm.class_mapper(type)
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\base.py", line 421, in class_mapper
    mapper = _inspect_mapped_class(class_, configure=configure)
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\base.py", line 400, in _inspect_mapped_class
    mapper._configure_all()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\mapper.py", line 1268, in _configure_all
    configure_mappers()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\mapper.py", line 3013, in configure_mappers
    mapper._post_configure_properties()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\mapper.py", line 1811, in _post_configure_properties
    prop.init()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\interfaces.py", line 184, in init
    self.do_init()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\relationships.py", line 1655, in do_init
    self._process_dependent_arguments()
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\orm\relationships.py", line 1680, in _process_dependent_arguments
    setattr(self, attr, attr_value())
  File "F:\Installations\Anaconda\lib\site-packages\sqlalchemy\ext\declarative\clsregistry.py", line 281, in __call__
    x = eval(self.arg, globals(), self._dict)
  File "<string>", line 1, in <module>
AttributeError: 'Table' object has no attribute 'added_by'

I managed to solve this. Apparently I was mixing up class names and table names, here is the working updated code, look at the updated foreign key data for 'added_by' column.

from datetime import datetime
from TasMar import  db, login_manager
from flask import  current_app
from flask_login import UserMixin
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

class User(db.Model, UserMixin):
    __tablename__ = 'tm_user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20),unique=True, nullable=False)
    email = db.Column(db.String(120),unique=True, nullable=False)
    image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
    password=  db.Column(db.String(120), nullable=False)

    #foreign keys accessing this table's primary keys
    added_by = db.relationship('Tasks',backref='addedby', lazy=True, foreign_keys='Tasks.added_by')
    assigned_to = db.relationship('Tasks',backref='user', lazy=True, foreign_keys='Tasks.assigned_to')

    def __repr__(self):
            return "User('{}','{}','{}')".format(self.username,self.email,self.image_file)



class Tasks(db.Model):
    __tablename__ = 'tm_task'
    task_id = db.Column(db.Integer, primary_key=True)
    parent_id = db.Column(db.Integer, db.ForeignKey('tm_task.task_id'),nullable=True)
    descr = db.Column(db.String(500), nullable=False)
    added_on = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    assigned_to = db.Column(db.Integer, db.ForeignKey('tm_user.id'),nullable=False)
    added_by = db.Column(db.Integer, db.ForeignKey('tm_user.id'),nullable=False)
    target_date = db.Column(db.DateTime,nullable=True,default=None)
    last_updated = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    remark = db.Column(db.Text)
    #foreign keys accessing this table's primary keys
    parent = db.relationship('Tasks', remote_side=[task_id]) #self referential
    status = db.Column(db.Integer, db.ForeignKey('tm_status.id'),nullable=False)
    type = db.Column(db.Integer, db.ForeignKey('tm_type.id'),nullable=False)
    urgency = db.Column(db.Integer, db.ForeignKey('tm_urgency.id'),nullable=False)

    def __repr__(self):
            return "Tasks('{}','{}','{}','{}')".format(self.descr,self.added_on,self.added_by,self.assigned_to)

class tm_status(db.Model):
    __tablename__ = 'tm_status'
    id = db.Column(db.Integer, primary_key=True)
    status = db.Column(db.String(20),unique=True,nullable=False)
    status_f = db.relationship('Tasks',backref='status_f', lazy=True, foreign_keys='Tasks.status')

    def __repr__(self):
            return "tm_status('{}')".format(self.status)

class tm_type(db.Model):
    __tablename__ = 'tm_type'
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(20),unique=True,nullable=False)
    type_f = db.relationship('Tasks',backref='type_f', lazy=True, foreign_keys='Tasks.type')

    def __repr__(self):
            return "tm_type('{}')".format(self.type)

class tm_urgency(db.Model):
    __tablename__ = 'tm_urgency'
    id = db.Column(db.Integer, primary_key=True)
    urgency = db.Column(db.String(20),unique=True,nullable=False)
    urgency_f = db.relationship('Tasks', backref='urgency_f', lazy=True, foreign_keys='Tasks.urgency')

    def __repr__(self):
            return "tm_urgency('{}')".format(self.urgency)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM