0

How can I dynamically update a field programmatically by specifying the column name in Flask-SQLAlchemy? I have a class PTc. It will only ever have one long row so I can pull all the info with the following:

Target = PTc.query.order_by(PTc.id).first()

I can manually update a field e.g. Target.price = 2 then commit. How can I update dynamically? i.e. When the program runs, it may want to update the price, amount or availability depending on the condition.

If I save column name to a variable, columnToUpdate = 'amount' then try Target.columnToUpdate = 10 it will of course fail because it thinks that is a column. Otherwise I am forced to check condition of each which could get cumbersome given the large number of columns :

if columnToUpdate == 'price'
   Target.price = 20
elif columnToUpdate =='amount':
     Target.amount = 20

...

elif columnToUpdate =='XYZ':
     Target.amount = ABC

Documentation only specifies insert, delete and select with minimal detail. The class :

class PTc(db.Model):
    # id column     
    id = db.Column(db.Integer, primary_key=True) 
    goldPrice       = db.Column(db.Integer, nullable=False)
    goldStock       = db.Column(db.Integer, nullable=False)
    goldPriceChange = db.Column(db.String(50), nullable=False)
    goldHistory     = db.Column(db.String(100), nullable=False)
    goldAverage     = db.Column(db.Integer, nullable=False)

    rmPrice         = db.Column(db.Integer, nullable=False)
    rmStock         = db.Column(db.Integer, nullable=False)
    rmPriceChange   = db.Column(db.String(50), nullable=False)
    rmHistory       = db.Column(db.String(100), nullable=False)
    rmAverage       = db.Column(db.Integer, nullable=False)

    gemsPrice         = db.Column(db.Integer, nullable=False)
    gemsStock         = db.Column(db.Integer, nullable=False)
    gemsPriceChange   = db.Column(db.String(50), nullable=False)
    gemsHistory       = db.Column(db.String(100), nullable=False)
    gemsAverage       = db.Column(db.Integer, nullable=False)

    oilPrice         = db.Column(db.Integer, nullable=False)
    oilStock         = db.Column(db.Integer, nullable=False)
    oilPriceChange   = db.Column(db.String(50), nullable=False)
    oilHistory       = db.Column(db.String(100), nullable=False)
    oilAverage       = db.Column(db.Integer, nullable=False)
5
  • 2
    Have you tried setattr(obj_name, "price", 20) ? Commented Jul 11, 2020 at 21:52
  • Afraid no joy with that: AttributeError: type object 'PTc' has no attribute 'setattr' Commented Jul 11, 2020 at 22:13
  • What does the class PTc look like, is it a Json/dict? Commented Jul 11, 2020 at 22:17
  • Updated class in description, it's fairly similar to the examples given in their tutorial flask-sqlalchemy.palletsprojects.com/en/2.x Commented Jul 11, 2020 at 22:21
  • 2
    @Murchie85 - setattr works for me. Note that it is a built-in function, not a class method. Commented Jul 11, 2020 at 22:50

2 Answers 2

1

The setattr(PTc, "goldPrice", 200) is what I was looking for, thanks to Gord for the solution.

It would be interested to see if there was another SQLAlchemy specific method given the documented class.field = x convention prevents the use of a variable as the field and would seem remarkable if they hadn't accounted for that.

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

1 Comment

how did you commit this to the DB? Specifically, how did you use the setattr() call?
1

That was extremely helpful! Thanks, @Gord Thompson and @Murchie85!

target = PTc.query.order_by(PTc.id).first()
setattr(target, column_name, data_to_insert)
db.session.commit()

This is the way to use it. Basically, this way you can use dynamic value for the column_name.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.