Coder Social home page Coder Social logo

erdot's Introduction

logo

Welcome to ERDot ๐Ÿ‘‹

PyPI License: MIT

Creates Entity Relationship Diagrams from JSON/YAML code.

Installation

to install ERDot:

pip install ERDot

you may also need to install graphvis to be able to create images of the dot files generated. If you don't want to install graphviz, you can copy the contents of the generated dot file into an online grapviz viewer.

CLI Usage

Usage: erdot [OPTIONS] INPUTFILE

  ERDot generates graphvis .dot files from the .json/.yml files INPUTFILE.

Options:
  -o, --outputFile TEXT  The graphvis dot file to write (.dot)
  -q, --quiet            Suppresses program information messages.
  --help                 Show this message and exit.

Note that after generating the .dot file, you will still need to output it to your desired format using graphviz. An example of how to do this:

$ erdot example.erd.json 

$ dot example.dot -Tpng -o imageFile.png

(You could also copy and paste the contents of the .dot file into an online graphviz viewer)

ERDJSON format:

{
    "tables":{
        ...
    },
    "relations":[
        ...
    ],
    "rankAdjustments":"...",
    "label":"..."
}   

Every single one of these sections are required, however, if you dont need that specific feature (for example label or rankAdjustments), just leave the value blank

table:

Each table inside of the table section of the ERDJSON document is formated like this:

"TableName": {
      "*PrimaryKey": "Int(10)",
      "+ForeignKey": "Int(10)",
      "RandomData": "Char(70)"
    }

the general idea is that the key is the column name, and the value is the type.

you will also notice the * and + next to the column names, these indicate primary and foriegn keys respectively. You can combine two of these together into a primary foreign key (a composite key consisting of two foreign keys), just by putting both a * and a + next to the name.

relations:

each element in the relations array of the ERDJSON document is formatted like this:

"TableOne:PrimaryKey 1--* TableTwo:ForeignKey"

There are three elements that make up the relation string, (1) the left hand side, (2) the cardinality indicator, and (3) the right hand side.

Left and Right hand side:

The sides of the relation string consist of two elements, separated by a :. the text before the : indicates what table it is in, and the text after the : indicates what specific column it should use to link. (note how you dont include the + or * in the specific column text).

Cardinality indicator:

Each relationship must have two of these cardinalities in the indicator, separated by --:

Cardinality    Syntax
0 or 1         ?
exactly 1      1
0 or more      *
1 or more      +

So for example, the following defines a relationship between Person's birthplaceID foreign key and BirthPlace's ID primary key that reads "every person has exactly one birth place, linked together using the birthplaceID":

Person:birthplaceID *--1 BirthPlace:ID

rankAdjustments

applies graphvis' rank adjustments to adjust where the tables appear in the final image. (note that it is only one string)

{ rank=min; TableOne Tabletwo }; // sets TableOne and TableTwo to be in the minimum rank (left)
{ rank=same; TableThree TableFour }; // sets TableThree and TableFour to be in the same rank
{ rank=max; TableFive }; // sets TableFive to be in the maximum rank (right)

Label

a string that sets what label will be drawn on top of the ERD, think of it like the title of the ERD.

Example ERDJSON:

{
    "tables":{
        "Person":{
            "*name":"char()",
            "height":"int()",
            "weight":"int()",
            "birthDate":"date()",
            "+birthPlaceID":"int()"
        },
        "BirthPlace":{
            "*id":"int()",
            "birthCity":"char()",
            "birthState":"char()",
            "birthCountry":"char()"
        }
    },
    "relations":[
        "Person:birthPlaceID *--1 BirthPlace:id"
    ],
    "rankAdjustments":"",
    "label":""
}

which then creates this image:

logo

The ERDYAML of the same image would look like:

tables:
  Person:
    "*name": char()
    height: int()
    weight: int()
    birthDate: date()
    "+birthPlaceID": int()
  BirthPlace:
    "*id": int()
    birthCity: char()
    birthState: char()
    birthCountry: char()
relations:
- Person:birthPlaceID *--1 BirthPlace:id
rankAdjustments: ''
label: ''

Author

๐Ÿ‘ค ehne

Show your support

Give a โญ๏ธ if this project helped you!


This README was generated with โค๏ธ by readme-md-generator

erdot's People

Contributors

ehne avatar tym-xqo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

erdot's Issues

Alternative key designation?

Hello,

(Still new to data modeling and ER diagramming)

In the README table section, when you say...

You can combine two of these together into a primary foreign key, just by putting both a * and a + next to the name

...is this the same visual representation as designating an "Alternative Key"?

Thank you

Change CLI to be simpler to use

current system:

erdot -i inputFile.erd.json -o outputFile.dot 

the -i value is a required one, so it could probably be reduced to just being the first argument, not requiring the -i.

erdot inputFile.erd.json -o outputFile.dot

the -o var probably doesn't need to be a required one, it should just use the same name as the input file (minus the erd.json).

erdot inputFile.erd.json

with the ability to customise the output file with the -o var.

Warning: Arrow type "32" unknown - ignoring with rankAdjustments

I made the following as test.json:

{
  "tables":{
      "label":{
        "*id":"1",
        "aid": "bla"
      },
      "order":{
        "*id": "12sd312asd34",
        "+b_aid": "bla",
        "+q_aid": "bla2"
      },
      "hole":{
        "*id": "sd9f8sd9fusdfuds98u8d8fu9ds8",
        "+first_aid": "bla",
        "+second_aid": "bla"
      },

      "pos":{
        "*id": "lplppasd1213124",
        "+b_aid": "bla3",
        "+q_aid": "bla2",
        "+p_id": "06991591-ef4a-48dc-8703-89c7cd43a8fb"
      },
      "on_1_event":{
        "*id": "asd2as4d1213124",
        "state": "OPEN",
        "+o_id": "12sd312asd34"
      },
      "on_2_event":{
        "*id": "asd2as4d1213124",
        "state": "OPEN",
        "+l_id": "lplppasd1213124"
      },
      "sub_1_event":{
        "*id": "1125dfa1",
        "+key20": "123ascas123as1d..",
        "event": "PENDING",
        "+o_id": "12sd312asd34"
      },
      "sub_2_event":{
        "*id": "1125dfa1",
        "+key20": "123ascas123as1d..",
        "event": "PENDING",
        "+l_id": "lplppasd1213124"
      }
      

  },
  "relations":[
      "hole:first_aid *--1 label:id",
      "hole:second_aid *--1 label:id",
      "pos:b_aid *--1 label:id",
      "pos:q_aid *--1 label:aid",
      "label:id 1--* hole:first_aid",
      "label:id 1--* hole:second_aid",
      "pos:p_id *--1 hole:id",
      "label:id 1--* order:b_aid",
      "label:id 1--* order:q_aid",
      "order:id 1--* on_1_event:o_id",
      "order:id 1--* sub_1_event:o_id",
      "pos:id 1--* on_2_event:l_id",
      "pos:id 1--* sub_2_event:l_id"
  ],
  "rankAdjustments":"{rank=min on_2_event pos sub_2_event}{rank=same label hole}{rank=max on_1_event order sub_1_event}",
  "label":""
}

and I got multiple errors Warning: Arrow type "32" unknown when running dot test.dot -Tpng -o test.png - then some outputs are missing the correct cardinalities. Please advise

shorten output

wondering if its possible to shorten the value so that the tables dont end up too large?

Python usage?

Hello,

Thank you for the neat tool. I'm trying to use ERDot within a Jupyter notebook, but failing.

Can you spot what I'm missing?

pip install ERDot

import json
import erdot

#Using your sample erd.json file

with open('test.erd.json') as datafile:
    data = json.load(datafile)

#Also tried: erdot datafile
erdot data

Both fail with:

File "<ipython-input-20-af1064bb5405>", line 7
    erdot data
          ^
SyntaxError: invalid syntax
---
File "<ipython-input-21-02b4ccd4d9ea>", line 7
    erdot datafile
          ^
SyntaxError: invalid syntax

But this works fine on the command line: erdot test.erd.json

Error: example.dot: syntax error in line 25 near '.'

Hello if i change table name "Perggon" to "Perg.gon" i have a error

Error: example.dot: syntax error in line 25 near '.'

line 25 in example.dot
Perg.gon [ label=<

part of my example.erd.json

"tables": {
"Perg.gon": {
"*name": "char()",
"height": "int()",
"weight": "int()",
"birthDate": "date()",
"+birthPlaceID": "int()"
}

}

name of table can be different , could you add quote character ?
"Perg.gon" [ label=<
thank you

ERD file parse error

Hello,
I haven't used ERDOT in a while. Feels like I'm missing something.

  1. Use JSON to create table structure and relationships (Check)
  2. Run erdot file.json to produce a file.json.dot file
  3. Open the .dot file in VS Code
  4. F1 / `ERD: Preview Current Window'
  5. Results in error (below)
  6. Testing on https://edotor.net/ results in a perfect graph

How do I troubleshoot this error?
image

make pipe work (read from stdin and write to stdout)

Hi, I would like to pipe the output of ERDot directly to dot like this:
erdot -o - example.erd.json | dot -Tsvg > example.svg
But presently these extraneous messages:

loaded example.erd.json
generated .dot code
saved graphvis dot code to -!

are mixed into the dot output and therefore the pipe fails.
Can you please move them to stderr instead of stdout?
Or maybe add an -q option (quiet) to suppress these extraneous messages?

Also, I would like to pipe the output of some other program into ERDot like this:

python3 json2erd.py < example.sqp.json | erdot > example.dot

Can you please make the input file name optional?
So in the absence of the input file name, erdot should read from stdin.
You can do that easily with fileinput() like this:

jsonLoaded = json.loads(''.join(fileinput.input(args.jsonfile)))

See this gist for a full example.

In fact the json2erd.py script I created:
https://gist.github.com/ckhung/c208ad5b72e7ebe216fd0bfc7fb1cb7a
is meant to convert the output of a sql ddl parser (such as iamcal/SQLParser)
to the input of an ER diagram renderer (such as your ehne/ERDot )
and it would be nice if the entire chain of commands can be streamlined by pipes.
My script also uses fileinput() to achieve the "input file or stdin" effect.

Thanks!

clarification about primary key and foreign key

The crows foot ER diagram created by ERDot looks really nice :-) I have updated my script to generate *.erd.json as input to ERDot and thereby generating a beautiful svg for the sakila sample database. You might consider including the more complex sakila.erd.json as an example input to ERDot.

The comments in README.md about the keys are however somewhat confusing. A composite key is a primary key composed of two or more fields. It is, however, unrelated to the case of '*+' prefix to a key. A primary key (*) which is simultaneously a foreign key (+) is syntactically possible but semantically dubious at best. The 2nd most voted answer actually makes more sense.

Also, the explanation about the relations and the cardinality indicator need to be fixed. By far the most comon case is:
ChildTable:ForeignKey1 *--1 ParentTable:PrimaryKey
In your example.erd.json for example, Person is a child table and BirthPlace is the parent table. The best article I can find by google is this but I am sure you can also find the clarification in textbooks, and you can look at the sakila schema for many more examples.

Keep up the good work!

TypeError when tables is a list

I have a python script that generates the necessary JSON.
It however generates the tables key as a list, which crashes ERDot:

TypeError: list indices must be integers or slices, not dict

My JSON:

{
   "label" : "",
   "rankAdjustments" : "",
   "relations" : [
      "Groups:preferences_id 1--1 Preferences:id",
      "UserInGroup:user_id 1--1 User:id",
      "UserInGroup:group_id 1--1 Groups:id",
      "Matches:user_id 1--1 User:id",
      "Matches:group_id 1--1 Groups:id",
      "User:preferences_id 1--1 Preferences:id"
   ],
   "tables" : [
      {
         "Groups" : {
            "id" : "int(11)",
            "name" : "varchar(125)",
            "preferences_id" : "int(11)"
         }
      },
      {
         "Preferences" : {
            "age" : "enum('puppy','young','adult','senior')",
            "care" : "enum('house_trained','special_needs')",
            "gender" : "enum('male','female')",
            "good_with_animals" : "tinyint(1)",
            "good_with_children" : "tinyint(1)",
            "id" : "int(11)",
            "type" : "enum('all','dog','cat')"
         }
      },
      {
         "User" : {
            "email_address" : "varchar(255)",
            "id" : "int(11)",
            "password" : "varchar(255)",
            "preferences_id" : "int(11)",
            "username" : "varchar(125)"
         }
      },
      {
         "UserInGroup" : {
            "group_id" : "int(11)",
            "id" : "int(11)",
            "user_id" : "int(11)"
         }
      }
   ]
}

A way to support distinguish the overlapping lines

Hello.

I am considering to adopt ERDot.
When some lines overlapping each others, currently ERDot overlaps lines without distinguishable marks
but would it be possible to render those overlaps with some specific marks
e.g., _|----|

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.