How can sqlalchemy work with custom class as the attributes

时光怂恿深爱的人放手 提交于 2019-12-25 07:59:52

问题


I am using sqlalchemy and flask-sqlalchemy, one of my db model comes with a state column

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(8))
    state = db.Column(db.Integer, default=ServerState.IN_PACKAGE, nullable=True)

    def init_state(self):

        self.state = State1

    def transit_state(self):

        self.state.next(self) 

The problem is that this state column is saved into db as a integer, but in order to implement a proper state machine, it is implemented as a Class:

class State1(BaseState):

    __int = 100
    __name = 'State1'

    @staticmethod
    def next(item):
        if item.contidition1 is None or item.condition2 is None:
            raise InvalidStateTransition

        item.state = State2

This works well and keeps the code clean, but the critical issue is that when I want to commit the Item to the db, it surely will give me error :

 Incorrect integer value: '<class 'app.models.Item.State1'>' for column 'state' at row 1

So, is there a way for the session, or python, to automatically convert the class to its int representation when save into the db, and convert from the int to its state class when it is retrieved from the db?


回答1:


You can use a TypeDecorator. Something like:

class StateType(TypeDecorator):
    impl = Integer

    def process_bind_param(self, value, dialect):
        return map_integer_to_my_state(value)

    def process_result_value(self, value, dialect):
        return map_my_state_to_integer(value)

Then you can use StateType as the type of the state column:

state = db.Column(StateType, ...)


来源:https://stackoverflow.com/questions/40257478/how-can-sqlalchemy-work-with-custom-class-as-the-attributes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!