Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to handle sqlalchemy onupdate when current context is empty?

I have a model of article which will have slug based on it's title, the model is like this:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text

Base = declarative_base()


class Article(Base):

    __tablename__ = 'article'

    id = Column(Integer, primary_key=True)
    title = Column(String(100), nullable=False)
    content = Column(Text)
    slug = Column(String(100), nullable=False,
                  default=lambda c: c.current_params['title'],
                  onupdate=lambda c: c.current_params['title'])

slug is taking title's value. So, everytime article slug will match it's title. But, when I edit the content without changing it's title, this exception is raised

(builtins.KeyError) 'title' [SQL: 'UPDATE article SET content=?, slug=?,
updated_at=? WHERE article = ?'] [parameters: [{'article_id': 1,
'content': 'blah blah blah'}]]

I guess that because current_params doesn't contain title. If, I change the lambda there and using if, slug will be None. So how can I handle this and keep the slug value match it's title?

like image 876
Mas Bagol Avatar asked Nov 14 '15 12:11

Mas Bagol


People also ask

How does SQLAlchemy update data?

Update table elements in SQLAlchemy. Get the books to table from the Metadata object initialized while connecting to the database. Pass the update query to the execute() function and get all the results using fetchall() function. Use a for loop to iterate through the results.

What is lazy dynamic SQLAlchemy?

Lazy parameter determines how the related objects get loaded when querying through relationships. Below listed are the four main lazy parameters. Typically when you query the database, the data get loaded at once; however, lazy parameter allows you to alternate the way they get loaded. lazy = 'select' (or True)

What is Session flush in SQLAlchemy?

session. flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction.

What is SQLAlchemy aliased?

The alias in SQL corresponds to a “renamed” version of a table or SELECT statement, which occurs anytime you say “SELECT * FROM table1 AS a”. The AS creates a new name for the table. Aliases allow any table or subquery to be referenced by a unique name.


1 Answers

You can use validates() decorator:

from sqlalchemy.orm import validates

class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.String)
    slug = db.Column(db.String(100), nullable=False)

    @validates('title')
    def update_slug(self, key, title):
        self.slug = title
        return title

Or events:

from sqlalchemy import event

class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    content = db.Column(db.String)
    slug = db.Column(db.String(100), nullable=False)

@event.listens_for(Article.title, 'set')
def update_slug(target, value, oldvalue, initiator):
    target.slug = value
like image 75
r-m-n Avatar answered Oct 08 '22 17:10

r-m-n