def columns(self, recurse=True, flags=<NUM_LIT:0>):
key = (recurse, flags)<EOL>try:<EOL><INDENT>return self.__cache[key]<EOL><DEDENT>except KeyError:<EOL><INDENT>output = odict()<EOL>if recurse:<EOL><INDENT>inherits = self.inherits()<EOL>if inherits:<EOL><INDENT>schema = orb.system.schema(inherits)<EOL>if not schema:<EOL><INDENT>raise orb.errors.ModelNotFound(schema=inherits)<EOL><DEDENT>else:<EOL><INDENT>iflags = (flags & ~orb.Column.Flags.Virtual) if flags else ~orb.Column.Flags.Virtual<EOL>ancest_columns = schema.columns(recurse=recurse, flags=iflags)<EOL>dups = set(ancest_columns.keys()).intersection(output.keys())<EOL>if dups:<EOL><INDENT>raise orb.errors.DuplicateColumnFound(schema=self, column='<STR_LIT:U+002C>'.join(dups))<EOL><DEDENT>else:<EOL><INDENT>output.update(ancest_columns)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>output.update(odict(<EOL>(col.name(), col) for col<EOL>in sorted(self.__columns.values(), key=lambda x: x.order())<EOL>if (not flags or col.testFlag(flags))<EOL>))<EOL>self.__cache[key] = output<EOL>return output<EOL><DEDENT>
Returns the list of column instances that are defined
for this table schema instance.

:param      recurse | <bool>
            flags   | <orb.Column.Flags>
            kind    | <orb.Column.Kind>

:return     {<str> column name: <orb.Column>, ..}