sqlalchemy InvalidRequestError

Issue

I’m using flask-sqlalchemy, this is not the first relations that i’ve built, but for some reason it gives me an error when i start flask:

sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class User->users'. Original exception was: 'Table' object has no attribute 'sender_id'

These are two models that i’m trying to connect via ForeignKeys:

User:

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))
    about_me = db.Column(db.String(140))
    last_seen = db.Column(db.DateTime, default=datetime.utcnow)
    #relations
    posts = db.relationship('Post', back_populates='author', lazy='dynamic')
    messages_sent = db.relationship('Message', foreign_keys='messages.sender_id',
                                    back_populates='author', lazy='dynamic')
    messages_received = db.relationship('Message', foreign_keys='messages.recipient_id',
                                        back_populates='recipient', lazy='dynamic')
    last_message_read_time = db.Column(db.DateTime)
    followed = db.relationship(
        'User', secondary=followers,
        primaryjoin=(followers.c.follower_id == id),
        secondaryjoin=(followers.c.followed_id == id),
        backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')

    def __repr__(self):
        return '<User {}>'.format(self.username)

And Messsage:

class Message(db.Model):
    __tablename__ = 'messages'
    id = db.Column(db.Integer, primary_key=True)
    sender_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    recipient_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
    #relations
    author = db.relationship('User', back_populates='messages_sent', lazy='dynamic')
    recipient = db.relationship('User', back_populates='messages_received', lazy='dynamic')

    def __repr__(self):
        return '<Message {}>'.format(self.body)

I’ve checked the database itself and it certainly has sender_id in the correct table, tried to change "foreign_keys" parameter to directly name of model Message.sender… Tried to change parameters of lazy on those relations. It still gives me same error.

Solution

This is subtle but messages in this case is a table so columns are referenced off of c, like messages.c.sender_id. To use the column of the model class (the mapped class) you would do Message.sender_id.

So…

messages_sent = db.relationship('Message', foreign_keys='messages.c.sender_id',
                                    back_populates='author', lazy='dynamic')

# OR
messages_sent = db.relationship('Message', foreign_keys='Message.sender_id',
                                    back_populates='author', lazy='dynamic')

There is some information here but it doesn’t explain the table vs class situation: handling-multiple-join-paths I think I would just use ORM style references until you are more comfortable and then you could use table references if needed.

Answered By – Ian Wilson

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published