def schema(self):
        """
        Either return the schema set in the constructor (or from previous calls) or create the default ColanderAlchemy
        schema for this model type.

        :return: This models Deform schema.
        """
        if '_schema' not in locals() or self._schema is None:
            self._schema = convert_schema(SQLAlchemyMapping(type(self)))
        return self._schema
    def test_conversion_equality(self):
        session = DBSession()
        PROJECT_ID = 2

        schema = convert_schema(SQLAlchemyMapping(Project, unknown='raise',))
        form = Form(schema, action='test', project_id=PROJECT_ID, buttons=('Save', 'Delete', 'Submit', 'Reopen', 'Approve', 'Disable'), use_ajax=False)
        model = session.query(Project).filter_by(id=2).first()
        data = model.dictify(schema)
        new_model = Project(appstruct=data)

        public_props = (name for name in dir(object) if not name.startswith('_'))
        for name in public_props:
            print name
            assert model.getattr(name) == new_model.getattr(name), "Converted models don't equal: %s, %s" % model.getattr(name) % new_model.getattr(name)

        print "Successfully read model, converted to data, converted back to model and the models are the same."
    def get_model(self):
        """
        Find a provisioning interface model based on the provided object_type and id.

        :return: Found model that is dictified and returned as JSON.
        """

        assert 'object_type' in self.request.matchdict and issubclass(eval(self.request.matchdict['object_type']),Base), "Error: Trying to lookup database with invalid type."
        assert 'id' in self.request.matchdict, "Error: Trying to lookup " + self.request.matchdict['object_type'] +" data from database without an id."
        object_type = eval(self.request.matchdict['object_type'])
        object_id = self.request.matchdict['id']

        model = self.session.query(object_type).filter_by(id=object_id).first()
#        print model

        if model:
            data = model.dictify(convert_schema(SQLAlchemyMapping(object_type, unknown='raise', ca_description=""), page='setup'))

            json_data = json.dumps(data)
            return {'values': json_data}
    def convert_sqlalchemy_model_to_data(self, model, schema=None, force_not_empty_lists=False, dates_as_string=True,
                                         bool_false_as_none=True):
        """
        Functionality behind CAModel dictify(), this is a recursive function that will call itself for each child.

        :param model: Model to dictify.
        :param schema: Schema to dictify for (mainly used for recursive functionality).
        :param force_not_empty_lists: Ensure there is always at least 1 element in sequences/lists.
        :param dates_as_string: Output dates as objects or strings (deform widgets are inconsistent with this...)
        :return: Deform compatible appstruct for the passed in CAModel.
        """
        if schema is None:
            # This will not take groupings into account
            schema = convert_schema(SQLAlchemyMapping(type(model)))

        data = {}
    
        if model is None:
            return data
    
        for node in schema:
            name = fix_schema_field_name(node.name)
    
            if hasattr(model, name):
                value = getattr(model, name, None)

                if isinstance(value, basestring):
                    if isinstance(value, unicode):
                        value = value.encode("utf-8")
                    value = unicode(value, "utf-8")
    
                if isinstance(value, date) and dates_as_string:
                    value = str(value)
    
                if isinstance(value, bool):
                    if hasattr(node.widget, 'true_val') and value:
                        value = node.widget.true_val
                    else:
                        if bool_false_as_none:
                            value = None
                        elif hasattr(node.widget, 'false_val'):
                            value = node.widget.false_val
    
                if isinstance(value, list):
                    node_list = []

                    while node.widget is not None and len(value) < node.widget.min_len:
                        value.append(node.children[0]._reg.cls())

                    for item in value:
                        node_list.append(self.convert_sqlalchemy_model_to_data(item,  node.children[0], force_not_empty_lists, dates_as_string))

                    if force_not_empty_lists and len(value) == 0:
                        node_list.append(self.convert_sqlalchemy_model_to_data(node.children[0]._reg.cls(),  node.children[0], force_not_empty_lists, dates_as_string))
    
                    data[node.name] = node_list
#                elif isinstance(node.typ, deform.FileData) and value is not None:
#                    tempstore = node.widget.tmpstore.tempstore
#                    data[node.name] = node.default
#                    if value is not None:
#                        randid = value.split("/")[-1]
#                        for file_uid in tempstore:
#                            if 'randid' in tempstore[file_uid] and (tempstore[file_uid]['randid']) == str(randid):
#                                data[node.name] = tempstore[file_uid]
#                                break
    
                elif len(node.children):
                    data[node.name] = self.convert_sqlalchemy_model_to_data(value,  node, force_not_empty_lists, dates_as_string)
    
                elif value is None:
                    data[node.name] = node.default
                else:
                    if isinstance(node.widget, deform.widget.SelectWidget):
                        label = None
                        for select_value, select_label in node.widget.values:
                            if select_value == value:
                                label = select_label
                                break
                        # Give a best effor to set the redbox label fields that go along with all select fields
                        if hasattr(model, name + "_label"):
                            data[node.name + "_label"] = label

                    data[node.name] = value
            elif len(node.children) > 0:
                node_data = self.convert_sqlalchemy_model_to_data(model, node.children, force_not_empty_lists, dates_as_string)
    
                # Fix data for select mapping schemas
#                if not ':' in node.name:
#                    data['schema_select'] = str(getattr(model, 'method_id', None))

                data[node.name] = node_data
    
        return data