Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide a tool to collect and generate the pydantic ERD based on dataloader and schemas #150

Open
allmonday opened this issue Dec 3, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@allmonday
Copy link
Owner

allmonday commented Dec 3, 2024

dataloader is a relationship to define and connect entities

if we provide enough information in dataloader (DRAFT)

class Loader(DataLoader):
    __relationships__ = {
        from: Company,
        from_key: user_id,
        to: User,
        relationship: '1 -> N, owns'
    }
    async def batch_load_fn(self, keys):
        ...

or defined in schema

class EntityA(BaseModel):
    __metadata__ = [
        { to: EntityB,  describe: "A.id == B.a_id",  loader: [] }
        { to: EntityC, func: Func }
    ]
    # a : obj
    # def resolve_a(self, loader)
    #      return loader.load(self.id)

then after collecting all Loaders, a Graph of ER can be generate.

It's a Doc

expected output, raw

image
@allmonday allmonday added the enhancement New feature or request label Dec 4, 2024
@allmonday allmonday self-assigned this Dec 4, 2024
@allmonday
Copy link
Owner Author

image

def get_data():
    counter = 1
    definitions = [
        dict(source=Product, target=Order, field='product_id'),
        dict(source=Product, target=History, field='product_id'),
        dict(source=Order, target=Buyer, field='order_id'),
        dict(source=Order, target=Snap, field='order_id'),
    ]

    node_map = {}
    nodes = []
    edges = []

    for d in definitions:
        source = d['source'].__name__
        target = d['target'].__name__
        field = d['field']

        if source not in node_map:
            node_map[source] = counter
            counter += 1
            nodes.append({ 'id': node_map[source], 'label': source, 'shape': 'box', 'color': '#fff' })

        if target not in node_map:
            node_map[target] = counter
            counter += 1
            nodes.append({ 'id': node_map[target], 'label': target, 'shape': 'box', 'color': '#fff' })
        
        edges.append({ 
            'from': node_map[source],
            'to': node_map[target],
            'label': field,
            'physics': { 'springLength': 100 },
            'arrows': { 'to': { 'enabled': True, 'type': 'arrow', 'scaleFactor': 0.4 }} })

    data = {
        'nodes': nodes,
        'edges': edges,
    }
    return data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant