Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
330 views
in Technique[技术] by (71.8m points)

python - How do I raise an exception when assigning to an attribute which is NOT mapped to an SQLAlchemy column?

With SQLAlchemy, I'm finding that sometimes I mis-type a name of an attribute which is mapped to a column, which results in rather difficult to catch errors:

class Thing(Base):
    foo = Column(String)


thing = Thing()
thing.bar = "Hello" # a typo, I actually meant thing.foo
assert thing.bar == "Hello" # works here, as thing.bar is a transient attribute created by the assignment above
session.add(thing)
session.commit() # thing.bar is not saved in the database, obviously
...
# much later
thing = session.query(Thing)...one()
assert thing.foo == "Hello" # fails
assert thing.bar == "Hello" # fails, there's no even such attribute

Is there a way to configure the mapped class so assigning to anything which is not mapped to an SQLAlchemy column would raise an exception?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, the solution seems to be to override __setattr__ method of the base class, which allows us to check if the atribute already exists before setting it.

class BaseBase(object):
    """
    This class is a superclass of SA-generated Base class,
    which in turn is the superclass of all db-aware classes
    so we can define common functions here
    """

    def __setattr__(self, name, value):
        """
        Raise an exception if attempting to assign to an atribute which does not exist in the model.
        We're not checking if the attribute is an SQLAlchemy-mapped column because we also want it to work with properties etc.
        See http://stackoverflow.com/questions/12032260/ for more details.
        """ 
        if name != "_sa_instance_state" and not hasattr(self, name):
            raise AttributeError("Attribute %s is not a mapped column of object %s" % (name, self))
        super(BaseBase, self).__setattr__(name, value)

Base = declarative_base(cls=BaseBase)

Sort of "strict mode" for SQLAlchemy...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...