Search code examples
pythonsqlalchemymarshmallowmarshmallow-sqlalchemy

AttributeError: 'dict' object has no attribute


I'm trying to use sqlalchemy and marshmallow to make an PUT endpoint to update some data in a model. I'm running into this error:

  File "/Users/ronak.patel/MLGit/pythonAPI/applications.py", line 129, in update
    update.applicationId = application_id
AttributeError: 'dict' object has no attribute 'applicationId'

which is tracing back to this piece of code:

    if update_application is not None:

        # turn the passed in application into a db object
        schema = ApplicationSchema()
        update = schema.load(body, session=db.session)

        # Set the id to the application we want to update
        update.applicationId = application_id

        # merge the new object into the old and commit it to the db
        db.session.merge(update)
        db.session.commit()

        # return updated application in the response
        data = schema.dump(update_application)

        return data, 200

specifically this part: update.applicationId = application_id

my ApplicationSchema model looks like this:

class Application(db.Model):
    __tablename__ = "application"

    applicationId           = db.Column(db.Integer, primary_key=True)
    applicantId             = db.Column(db.Integer, db.ForeignKey('applicant.applicantId'))
    channel                 = db.Column(db.String(80), nullable=True)
    type                    = db.Column(db.String(80), nullable=True)
    offerId                 = db.Column(db.String(80), nullable=True)
    ipAddress               = db.Column(db.String(80), nullable=True)
    neuroIdIdentifier       = db.Column(db.String(80), nullable=True)
    threatmetrixSessionId   = db.Column(db.String(80), nullable=True)
    applicationAgreements   = db.Column(db.String(80), nullable=True)
    cardholderAgreements    = db.Column(db.String(80), nullable=True)
    electronicCommunication = db.Column(db.String(80), nullable=True)
    privacyPolicy           = db.Column(db.String(80), nullable=True)
    termsOfService          = db.Column(db.String(80), nullable=True)
    disclosureHtml          = db.Column(db.String(80), nullable=True)
    reviewPageHtml          = db.Column(db.String(80), nullable=True)
    status                  = db.Column(db.String(80), default='processing', nullable=True)
    timestamp               = db.Column(
        db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
    )
    
class ApplicationSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Application
        include_relationships = True   

which has applicationId... so I'm a bit confused why its telling me that AttributeError: 'dict' object has no attribute 'applicationId'?


Solution

  • It looks like you need to set the load_instance Meta class attribute to True, according to marshmallow-sqlalchemy docs. As suggested by G. Anderson, you can try to print the update object's type for confirmation, but it seems you are getting a default dict as the deserialized data, instead of an instance of your Application model, which could be achieved by doing the above-mentioned trick. The code could be written like this:

    class ApplicationSchema(SQLAlchemyAutoSchema):
        class Meta:
            model = Application
            include_relationships = True
            load_instance = True