matt
matt

Reputation: 753

Computing field values on save?

class Quote(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.Text)    
    votes = db.Column(db.Integer)
    author_id = db.Column(db.Integer, db.ForeignKey('author.id'))    
    date_added = db.Column(db.DateTime,default=datetime.datetime.now())    
    last_letter = db.Column(db.String(1))

I have a Model that looks like the above. I want last_letter to be the last letter of whatever the content is. Where should I place this logic so that it will occur every time a model is saved? I'm reading about Hybrid Properties and stuff and I'm not sure which way is the correct one to go.

Upvotes: 1

Views: 226

Answers (2)

m.brindley
m.brindley

Reputation: 1228

last_letter could be decorated with @property and defined

@property
def last_letter(self):
    return self.content[-1]

Disclaimer: I just learned how to use decorators and am using them everywhere

Upvotes: 0

alonisser
alonisser

Reputation: 12068

1.the Naive way: you can use sqlalchemy column default value to set something like:

last_letter = db.Column(db.char, default=content[len(content)-1:])

didn't check if that would actually work, guess not.

2.you can also do something like adding this init to the class:

def __init__(self,id,content,votes,auther_id,date_added):
    self.id = id
    self.content = content
    #yadda yadda etc
    self.last_letter = content[len(content)-1:] #or something similiar
  1. or you could use "listen" to the "before insert" event and add this dynamically as explained here.

  2. you can use sql computed column with an sql trigger (in the db) without sqlalchemy.

  3. you can probably use a sqlalchemy mapper sql expression as a hybrid property, also I didn't try that myself, look simple enough and probably is the most elegant way to do this.

Upvotes: 1

Related Questions