Pratik Khadloya
Pratik Khadloya

Reputation: 12869

SqlAlchemy non persistent column

I am trying to define a model using sqlalchemy such that one of the columns i only need in memory for processing, i do not have a corresponding database column for that. I need it such that when i save the in memory object, it should not try to persist that special column.

More context: I am mapping a json object to an sql alchemy object using python marshmallow library. In the json response i have additional fields which i do not need in the database but do need in memory for computation.

I searched for the sqlalchemy docs, but could not find a way to skip the persistence of certain columns.

class AdSchema(Schema):
  """Schema Mapping class."""

  id = fields.Int(dump_only=True)
  available_formats = fields.List(fields.Str())

  @post_load
  def make_ad(self, data):
    return AdModel(**data)

class AdModel(Base):
  """Ad ORM class."""
  __tablename__ = 'ad_model'

  id = Column(Integer, primary_key=True)

Am i missing something here?

What I am essentially looking for is a "virtual" attribute, similar to what is available in Rails ORM How to add a virtual attribute to a model in Ruby on Rails?

Upvotes: 7

Views: 2427

Answers (2)

Brad
Brad

Reputation: 11515

If you just add a variable to a db.Model-derived calss that is a "normal" data type (i.e. a string or integer) - as opposed to a db.Column - it can be used, and does not appear to have any affect on the actual database.

Upvotes: 1

jones-chris
jones-chris

Reputation: 691

I was able to get around this by doing the following:

class MyModel(Base):
    __tablename__ = 'my_model'

    id = Column(Integer, primary_key=True)

    def __init__(self, **kwargs):
        self.non_persisted_column = kwargs['non_persisted_column']
        kwargs.pop('non_peristed_column')
        super().__init__(kwargs)

Effectively, a class attribute non_persisted_column is added to the class in the __init__ method. Then, non_persisted_column is removed from kwargs before kwargs is passed into the SQLAlchemy Base super class's __init__ method, so SQLAlchemy will not raise an error and will not persist non_persisted_column to the database.

Upvotes: 1

Related Questions