简体   繁体   中英

Encoding a binary tree to json

I'm using the sqlalchemy to store a binary tree data in the db:

class Distributor(Base):
    __tablename__ = "distributors"

    id = Column(Integer, primary_key=True)
    upline_id = Column(Integer, ForeignKey('distributors.id'))
    left_id = Column(Integer, ForeignKey('distributors.id'))
    right_id = Column(Integer, ForeignKey('distributors.id'))

how can I generate json "tree" format data like the above listed:

{'id':1,children:[{'id':2, children:[{'id':3, 'id':4}]}]}

I'm guessing you're asking to store the data in a JSON format? Or are you trying to construct JSON from the standard relational data?

If the former, why don't you just create entries like:

{id: XX, parentId: XX, left: XX, right: XX, value: "foo"}

For each of the nodes, and then reconstruct the tree manually from the entries? Just start form the head (parentId == null) and then assemble the branches.

You could also add an additional identifier for the tree itself, in case you have multiple trees in the database. Then you would just query where the treeId was XXX, and then construct the tree from the entries.

I hesitate to provide this answer, because I'm not sure I really understand your the problem you're trying to solve (A binary tree, JSON, sqlalchemy, none of these are problems).

What you can do with this kind of structure is to iterate over each row, adding edges as you go along. You'll start with what is basically a cache of objects; which will eventually become the tree you need.

import collections
idmap = collections.defaultdict(dict)
for distributor in session.query(Distributor):
    dist_dict = idmap[distributor.id]
    dist_dict['id'] = distributor.id
    dist_dict.setdefault('children', [])
    if distributor.left_id:
        dist_dict.['children'].append(idmap[distributor.left_id])
    if distributor.right_id:
        dist_dict.['children'].append(idmap[distributor.right_id])

So we've got a big collection of linked up dicts that can represent the tree. We don't know which one is the root, though;

root_dist = session.query(Distributor).filter(Distributor.upline_id == None).one()
json_data = json.dumps(idmap[root_dist.id])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM