If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

There are a couple of issues about security (what objects should be filtered for output and wheter the filter should use dynamic or static mapping, perhaps using a "sanitize" arg). Also it could be improved for fastest serialization and code optimization.

 

    This snippet outputs DAL/Table/Field instances as dict/JSON/XML

    Copyright (C) 2013  Alan Etkin

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of the
    License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

       Affero GPLv3 License

 

 

def DB_AS_DICT(db, flat=False):
    db_as_dict = dict(items={}, tables=[], uri=str(db))
    for table in db:
        tablename = str(table)
        db_as_dict["tables"].append(tablename)
        db_as_dict["items"][tablename] = TABLE_AS_DICT(table, flat)
    return db_as_dict

def TABLE_AS_DICT(table, flat=False):
    tablename = str(table)
    table_as_dict = dict(name=tablename, items={}, fields=[])
    for field in table:
        if field.readable or field.writable:
            table_as_dict["fields"].append(field.name)
            table_as_dict["items"][field.name] = \
                FIELD_AS_DICT(field, flat)
    return table_as_dict

def FIELD_AS_DICT(field, flat=False):
    def flatten(obj):
        if flat:
            if isinstance(obj, type):
                try:
                    obj = str(obj).split("'")[1]
                except IndexError:
                    obj = str(obj)
            elif not isinstance(obj, (int, long, basestring, dict,
                                      list, float, tuple, bool,
                                      None.__class__)):
                obj = str(obj)
        return obj
    def filter_requires(r):
        for k, v in r.items():
            if k == "other":
                r[k] = {flatten(type(v)): v.__dict__}
        return r
    if isinstance(field.requires, (tuple, list, set)):
        requires = dict([(flatten(type(r)),
                        filter_requires(r.__dict__)) for
                         r in field.requires])
    else:
        requires = {flatten(type(field.requires)):
                    filter_requires(field.requires.__dict__)}

    return dict(colname="%s.%s" % (field.tablename, field.name),
                name=field.name, label=flatten(field.label),
                default=flatten(field.default),
                type=flatten(field.type), requires=requires)

def FIELD_AS_XML(field):
    from serializers import xml
    d = FIELD_AS_DICT(field, True)
    return xml(d)

def TABLE_AS_XML(table):
    from serializers import xml
    d = TABLE_AS_DICT(table, True)
    return xml(d)

def DB_AS_XML(db):
    from serializers import xml
    d = DB_AS_DICT(db, True)
    return xml(d)

# Write the db scheme to an xml file
with open("scheme.xml", "wb") as myfile:
    myfile.write(DB_AS_XML(db))

Related slices

Comments (1)

  • Login to post



  • 0
    spametki 8 years ago

    Note: an updated version of this code was included in trunk as an experimental feature.

     

    The DAL commands are

    db.as_dict(<flat=False, sanitize=True>)
    table.as_dict(<flat=False, sanitize=True>)
    field.as_dict(<flat=False, sanitize=True>)
    
    db.as_xml(<sanitize=True>)
    table.as_xml(<sanitize=True>)
    field.as_xml(<sanitize=True>)
    
    db.as_json(<sanitize=True>)
    table.as_json(<sanitize=True>)
    field.as_json(<sanitize=True>)
    

Hosting graciously provided by:
Python Anywhere