There may be many ways, but you need to use @validates :
from sqlalchemy import * from sqlalchemy.orm import * from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class A(Base): __tablename__ = 'a' id = Column(Integer, primary_key=True) readonly1 = Column(String) readonly2 = Column(String) @validates('readonly1', 'readonly2') def _write_once(self, key, value): existing = getattr(self, key) if existing is not None: raise ValueError("Field '%s' is write-once" % key) return value a1 = A() a1.readonly1 = 'foo' assert a1.readonly1 == 'foo' try: a1.readonly1 = 'bar' assert False except ValueError, e: print e e = create_engine("sqlite://") Base.metadata.create_all(e) s = Session(e) s.add(A(readonly1='foo', readonly2='bar')) s.commit() a2 = s.query(A).first() try: a2.readonly2 = 'bar2' assert False except ValueError, e: print e
@validates is simply a shorthand for using attribute events that you could use to create other ways to customize it.
source share