Read in inputs.yml and produce a GraphViz representation of the tables


In [1]:
import os
import yaml

import cea.scripts
import cea.interfaces.dashboard.inputs

from jinja2 import Template

import cea.inputlocator
import cea.config

config = cea.config.Configuration()
locator = cea.inputlocator.InputLocator(scenario=config.scenario)
schemas = cea.scripts.schemas()

OUTPUT_PATH = os.path.join(os.path.dirname(cea.config.__file__), "..", "docs", "tables_diagram.gv")

In [2]:
inputs_yml = os.path.abspath(os.path.join(os.path.dirname(cea.interfaces.dashboard.inputs.__file__), "inputs.yml"))

with open(inputs_yml, 'r') as fp:
    inputs = yaml.load(fp)

inputs


Out[2]:
{'air-conditioning-systems': {'fields': [{'name': 'Name', 'type': 'str'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_air_conditioning_systems',
      'sheet': 'COOLING'}},
    'name': 'type_cs',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_air_conditioning_systems',
      'sheet': 'HEATING'}},
    'name': 'type_hs',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_air_conditioning_systems',
      'sheet': 'HOT_WATER'}},
    'name': 'type_dhw',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_air_conditioning_systems',
      'sheet': 'CONTROLLER'}},
    'name': 'type_ctrl',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_air_conditioning_systems',
      'sheet': 'VENTILATION'}},
    'name': 'type_vent',
    'type': 'choice'},
   {'name': 'heat_starts', 'type': 'date'},
   {'name': 'heat_ends', 'type': 'date'},
   {'name': 'cool_starts', 'type': 'date'},
   {'name': 'cool_ends', 'type': 'date'}],
  'location': 'get_building_air_conditioning',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'architecture': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'void_deck', 'type': 'int'},
   {'constraints': {'max': 1}, 'name': 'Es', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'Hs_ag', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'Hs_bg', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'Ns', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'wwr_north', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'wwr_east', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'wwr_south', 'type': 'float'},
   {'constraints': {'max': 1}, 'name': 'wwr_west', 'type': 'float'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'CONSTRUCTION'}},
    'name': 'type_cons',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'TIGHTNESS'}},
    'name': 'type_leak',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'ROOF'}},
    'name': 'type_roof',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'SHADING'}},
    'name': 'type_shade',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'WALL'}},
    'name': 'type_wall',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'FLOOR'}},
    'name': 'type_floor',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'FLOOR'}},
    'name': 'type_base',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_envelope_systems',
      'sheet': 'WINDOW'}},
    'name': 'type_win',
    'type': 'choice'}],
  'location': 'get_building_architecture',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'indoor-comfort': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'Ths_set_C', 'type': 'float'},
   {'name': 'Ths_setb_C', 'type': 'float'},
   {'name': 'Tcs_set_C', 'type': 'float'},
   {'name': 'Tcs_setb_C', 'type': 'float'},
   {'name': 'RH_min_pc', 'type': 'float'},
   {'name': 'RH_max_pc', 'type': 'float'},
   {'name': 'Ve_lpspax', 'type': 'float'}],
  'location': 'get_building_comfort',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'internal-loads': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'Occ_m2pax', 'type': 'float'},
   {'name': 'Qs_Wpax', 'type': 'float'},
   {'name': 'X_ghpax', 'type': 'float'},
   {'name': 'Ea_Wm2', 'type': 'float'},
   {'name': 'El_Wm2', 'type': 'float'},
   {'name': 'Epro_Wm2', 'type': 'float'},
   {'name': 'Qcre_Wm2', 'type': 'float'},
   {'name': 'Ed_Wm2', 'type': 'float'},
   {'name': 'Ev_kWveh', 'type': 'float'},
   {'name': 'Qcpro_Wm2', 'type': 'float'},
   {'name': 'Qhpro_Wm2', 'type': 'float'},
   {'name': 'Vww_lpdpax', 'type': 'float'},
   {'name': 'Vw_lpdpax', 'type': 'float'}],
  'location': 'get_building_internal',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'supply-systems': {'fields': [{'name': 'Name', 'type': 'str'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_supply_assemblies',
      'sheet': 'COOLING'}},
    'name': 'type_cs',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_supply_assemblies',
      'sheet': 'HOT_WATER'}},
    'name': 'type_dhw',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_supply_assemblies',
      'sheet': 'ELECTRICITY'}},
    'name': 'type_el',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_supply_assemblies',
      'sheet': 'HEATING'}},
    'name': 'type_hs',
    'type': 'choice'}],
  'location': 'get_building_supply',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'surroundings': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'floors_ag', 'type': 'int'},
   {'name': 'height_ag', 'type': 'float'},
   {'name': 'REFERENCE', 'type': 'str'}],
  'location': 'get_surroundings_geometry',
  'parent': 'None',
  'pk': 'Name',
  'type': 'shp'},
 'typology': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'YEAR', 'type': 'year'},
   {'choice_properties': {'lookup': {'column': 'STANDARD',
      'path': 'get_database_construction_standards',
      'sheet': 'STANDARD_DEFINITION'}},
    'name': 'STANDARD',
    'type': 'choice'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_use_types_properties',
      'sheet': 'INTERNAL_LOADS'}},
    'name': '1ST_USE',
    'type': 'choice'},
   {'constraints': {'max': 1}, 'name': '1ST_USE_R', 'type': 'float'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_use_types_properties',
      'sheet': 'INTERNAL_LOADS'},
     'none_value': 'NONE'},
    'name': '2ND_USE',
    'type': 'choice'},
   {'constraints': {'max': 1}, 'name': '2ND_USE_R', 'type': 'float'},
   {'choice_properties': {'lookup': {'column': 'code',
      'path': 'get_database_use_types_properties',
      'sheet': 'INTERNAL_LOADS'},
     'none_value': 'NONE'},
    'name': '3RD_USE',
    'type': 'choice'},
   {'constraints': {'max': 1}, 'name': '3RD_USE_R', 'type': 'float'},
   {'name': 'REFERENCE', 'type': 'str'}],
  'location': 'get_building_typology',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'dbf'},
 'zone': {'fields': [{'name': 'Name', 'type': 'str'},
   {'name': 'floors_bg', 'type': 'int'},
   {'name': 'floors_ag', 'type': 'int'},
   {'name': 'height_bg', 'type': 'float'},
   {'name': 'height_ag', 'type': 'float'},
   {'name': 'REFERENCE', 'type': 'str'}],
  'location': 'get_zone_geometry',
  'parent': 'zone',
  'pk': 'Name',
  'type': 'shp'}}

In [3]:
table_template = """
{{locator}} [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">{{table}}</td></tr>
        {% for field in fields %}<tr><td port="{{field.name}}" align="left">{{field.type}}: {{field.name}}</td></tr>
        {% endfor %}
    </table>>];
"""

In [4]:
table_defs = []

for table in inputs.keys():
    lm = inputs[table]["location"]
    fields = inputs[table]["fields"]
    table_defs.append(Template(table_template).render(locator=lm, table=table, fields=fields))

In [5]:
print "\n".join(table_defs)


get_building_air_conditioning [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">air-conditioning-systems</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="type_cs" align="left">choice: type_cs</td></tr>
        <tr><td port="type_hs" align="left">choice: type_hs</td></tr>
        <tr><td port="type_dhw" align="left">choice: type_dhw</td></tr>
        <tr><td port="type_ctrl" align="left">choice: type_ctrl</td></tr>
        <tr><td port="type_vent" align="left">choice: type_vent</td></tr>
        <tr><td port="heat_starts" align="left">date: heat_starts</td></tr>
        <tr><td port="heat_ends" align="left">date: heat_ends</td></tr>
        <tr><td port="cool_starts" align="left">date: cool_starts</td></tr>
        <tr><td port="cool_ends" align="left">date: cool_ends</td></tr>
        
    </table>>];

get_zone_geometry [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">zone</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="floors_bg" align="left">int: floors_bg</td></tr>
        <tr><td port="floors_ag" align="left">int: floors_ag</td></tr>
        <tr><td port="height_bg" align="left">float: height_bg</td></tr>
        <tr><td port="height_ag" align="left">float: height_ag</td></tr>
        <tr><td port="REFERENCE" align="left">str: REFERENCE</td></tr>
        
    </table>>];

get_building_supply [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">supply-systems</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="type_cs" align="left">choice: type_cs</td></tr>
        <tr><td port="type_dhw" align="left">choice: type_dhw</td></tr>
        <tr><td port="type_el" align="left">choice: type_el</td></tr>
        <tr><td port="type_hs" align="left">choice: type_hs</td></tr>
        
    </table>>];

get_building_comfort [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">indoor-comfort</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="Ths_set_C" align="left">float: Ths_set_C</td></tr>
        <tr><td port="Ths_setb_C" align="left">float: Ths_setb_C</td></tr>
        <tr><td port="Tcs_set_C" align="left">float: Tcs_set_C</td></tr>
        <tr><td port="Tcs_setb_C" align="left">float: Tcs_setb_C</td></tr>
        <tr><td port="RH_min_pc" align="left">float: RH_min_pc</td></tr>
        <tr><td port="RH_max_pc" align="left">float: RH_max_pc</td></tr>
        <tr><td port="Ve_lpspax" align="left">float: Ve_lpspax</td></tr>
        
    </table>>];

get_surroundings_geometry [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">surroundings</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="floors_ag" align="left">int: floors_ag</td></tr>
        <tr><td port="height_ag" align="left">float: height_ag</td></tr>
        <tr><td port="REFERENCE" align="left">str: REFERENCE</td></tr>
        
    </table>>];

get_building_architecture [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">architecture</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="void_deck" align="left">int: void_deck</td></tr>
        <tr><td port="Es" align="left">float: Es</td></tr>
        <tr><td port="Hs_ag" align="left">float: Hs_ag</td></tr>
        <tr><td port="Hs_bg" align="left">float: Hs_bg</td></tr>
        <tr><td port="Ns" align="left">float: Ns</td></tr>
        <tr><td port="wwr_north" align="left">float: wwr_north</td></tr>
        <tr><td port="wwr_east" align="left">float: wwr_east</td></tr>
        <tr><td port="wwr_south" align="left">float: wwr_south</td></tr>
        <tr><td port="wwr_west" align="left">float: wwr_west</td></tr>
        <tr><td port="type_cons" align="left">choice: type_cons</td></tr>
        <tr><td port="type_leak" align="left">choice: type_leak</td></tr>
        <tr><td port="type_roof" align="left">choice: type_roof</td></tr>
        <tr><td port="type_shade" align="left">choice: type_shade</td></tr>
        <tr><td port="type_wall" align="left">choice: type_wall</td></tr>
        <tr><td port="type_floor" align="left">choice: type_floor</td></tr>
        <tr><td port="type_base" align="left">choice: type_base</td></tr>
        <tr><td port="type_win" align="left">choice: type_win</td></tr>
        
    </table>>];

get_building_typology [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">typology</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="YEAR" align="left">year: YEAR</td></tr>
        <tr><td port="STANDARD" align="left">choice: STANDARD</td></tr>
        <tr><td port="1ST_USE" align="left">choice: 1ST_USE</td></tr>
        <tr><td port="1ST_USE_R" align="left">float: 1ST_USE_R</td></tr>
        <tr><td port="2ND_USE" align="left">choice: 2ND_USE</td></tr>
        <tr><td port="2ND_USE_R" align="left">float: 2ND_USE_R</td></tr>
        <tr><td port="3RD_USE" align="left">choice: 3RD_USE</td></tr>
        <tr><td port="3RD_USE_R" align="left">float: 3RD_USE_R</td></tr>
        <tr><td port="REFERENCE" align="left">str: REFERENCE</td></tr>
        
    </table>>];

get_building_internal [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightblue">internal-loads</td></tr>
        <tr><td port="Name" align="left">str: Name</td></tr>
        <tr><td port="Occ_m2pax" align="left">float: Occ_m2pax</td></tr>
        <tr><td port="Qs_Wpax" align="left">float: Qs_Wpax</td></tr>
        <tr><td port="X_ghpax" align="left">float: X_ghpax</td></tr>
        <tr><td port="Ea_Wm2" align="left">float: Ea_Wm2</td></tr>
        <tr><td port="El_Wm2" align="left">float: El_Wm2</td></tr>
        <tr><td port="Epro_Wm2" align="left">float: Epro_Wm2</td></tr>
        <tr><td port="Qcre_Wm2" align="left">float: Qcre_Wm2</td></tr>
        <tr><td port="Ed_Wm2" align="left">float: Ed_Wm2</td></tr>
        <tr><td port="Ev_kWveh" align="left">float: Ev_kWveh</td></tr>
        <tr><td port="Qcpro_Wm2" align="left">float: Qcpro_Wm2</td></tr>
        <tr><td port="Qhpro_Wm2" align="left">float: Qhpro_Wm2</td></tr>
        <tr><td port="Vww_lpdpax" align="left">float: Vww_lpdpax</td></tr>
        <tr><td port="Vw_lpdpax" align="left">float: Vw_lpdpax</td></tr>
        
    </table>>];

In [6]:
databases = set()  # (lm, sheet)
connections = set()  # con

for ltable in inputs:
    lm = inputs[ltable]["location"]
    for field in inputs[ltable]["fields"]:
        if field["type"] == "choice":
            lfield = field["name"]
            rtable = field["choice_properties"]["lookup"]["path"]
            sheet = field["choice_properties"]["lookup"]["sheet"]
            rfield = field["choice_properties"]["lookup"]["column"]
            databases.add((rtable, sheet))
            connections.add((lm, lfield, rtable, sheet, rfield))

databases


Out[6]:
{('get_database_air_conditioning_systems', 'CONTROLLER'),
 ('get_database_air_conditioning_systems', 'COOLING'),
 ('get_database_air_conditioning_systems', 'HEATING'),
 ('get_database_air_conditioning_systems', 'HOT_WATER'),
 ('get_database_air_conditioning_systems', 'VENTILATION'),
 ('get_database_construction_standards', 'STANDARD_DEFINITION'),
 ('get_database_envelope_systems', 'CONSTRUCTION'),
 ('get_database_envelope_systems', 'FLOOR'),
 ('get_database_envelope_systems', 'ROOF'),
 ('get_database_envelope_systems', 'SHADING'),
 ('get_database_envelope_systems', 'TIGHTNESS'),
 ('get_database_envelope_systems', 'WALL'),
 ('get_database_envelope_systems', 'WINDOW'),
 ('get_database_supply_assemblies', 'COOLING'),
 ('get_database_supply_assemblies', 'ELECTRICITY'),
 ('get_database_supply_assemblies', 'HEATING'),
 ('get_database_supply_assemblies', 'HOT_WATER'),
 ('get_database_use_types_properties', 'INTERNAL_LOADS')}

In [7]:
connections


Out[7]:
{('get_building_air_conditioning',
  'type_cs',
  'get_database_air_conditioning_systems',
  'COOLING',
  'code'),
 ('get_building_air_conditioning',
  'type_ctrl',
  'get_database_air_conditioning_systems',
  'CONTROLLER',
  'code'),
 ('get_building_air_conditioning',
  'type_dhw',
  'get_database_air_conditioning_systems',
  'HOT_WATER',
  'code'),
 ('get_building_air_conditioning',
  'type_hs',
  'get_database_air_conditioning_systems',
  'HEATING',
  'code'),
 ('get_building_air_conditioning',
  'type_vent',
  'get_database_air_conditioning_systems',
  'VENTILATION',
  'code'),
 ('get_building_architecture',
  'type_base',
  'get_database_envelope_systems',
  'FLOOR',
  'code'),
 ('get_building_architecture',
  'type_cons',
  'get_database_envelope_systems',
  'CONSTRUCTION',
  'code'),
 ('get_building_architecture',
  'type_floor',
  'get_database_envelope_systems',
  'FLOOR',
  'code'),
 ('get_building_architecture',
  'type_leak',
  'get_database_envelope_systems',
  'TIGHTNESS',
  'code'),
 ('get_building_architecture',
  'type_roof',
  'get_database_envelope_systems',
  'ROOF',
  'code'),
 ('get_building_architecture',
  'type_shade',
  'get_database_envelope_systems',
  'SHADING',
  'code'),
 ('get_building_architecture',
  'type_wall',
  'get_database_envelope_systems',
  'WALL',
  'code'),
 ('get_building_architecture',
  'type_win',
  'get_database_envelope_systems',
  'WINDOW',
  'code'),
 ('get_building_supply',
  'type_cs',
  'get_database_supply_assemblies',
  'COOLING',
  'code'),
 ('get_building_supply',
  'type_dhw',
  'get_database_supply_assemblies',
  'HOT_WATER',
  'code'),
 ('get_building_supply',
  'type_el',
  'get_database_supply_assemblies',
  'ELECTRICITY',
  'code'),
 ('get_building_supply',
  'type_hs',
  'get_database_supply_assemblies',
  'HEATING',
  'code'),
 ('get_building_typology',
  '1ST_USE',
  'get_database_use_types_properties',
  'INTERNAL_LOADS',
  'code'),
 ('get_building_typology',
  '2ND_USE',
  'get_database_use_types_properties',
  'INTERNAL_LOADS',
  'code'),
 ('get_building_typology',
  '3RD_USE',
  'get_database_use_types_properties',
  'INTERNAL_LOADS',
  'code'),
 ('get_building_typology',
  'STANDARD',
  'get_database_construction_standards',
  'STANDARD_DEFINITION',
  'STANDARD')}

In [8]:
db_template = """
{{locator}}_{{sheet}} [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightgrey">{{table}}</td></tr>
        {% for field in fields %}<tr><td port="{{field.name}}" align="left">{{field.type}}: {{field.name}}</td></tr>
        {% endfor %}
    </table>>];
"""

db_defs = []

for lm, sheet in databases:
    xlsx = os.path.basename(getattr(locator, lm)())
    table = "{file}:{sheet}".format(file=xlsx, sheet=sheet)
    fields = []
    for fn in schemas[lm]["schema"][sheet].keys():
        name = fn.replace("&", "")
        fields.append({"name": name, "type": schemas[lm]["schema"][sheet][fn]["types_found"][0]})
    db_defs.append(Template(db_template).render(locator=lm, sheet=sheet, table=table, fields=fields))
    
print db_defs[0]


get_database_envelope_systems_ROOF [shape=none, margin=0, label=<
    <table border="0" cellborder="1" cellspacing="0" cellpadding="4" >
        <tr><td bgcolor="lightgrey">ENVELOPE.xls:ROOF</td></tr>
        <tr><td port="e_roof" align="left">float: e_roof</td></tr>
        <tr><td port="code" align="left">string: code</td></tr>
        <tr><td port="Description" align="left">string: Description</td></tr>
        <tr><td port="GHG_ROOF_kgCO2m2" align="left">float: GHG_ROOF_kgCO2m2</td></tr>
        <tr><td port="a_roof" align="left">float: a_roof</td></tr>
        <tr><td port="r_roof" align="left">float: r_roof</td></tr>
        <tr><td port="U_roof" align="left">float: U_roof</td></tr>
        
    </table>>];

In [9]:
con_defs = []

for ltable, lfield, rtable, sheet, rfield in connections:
    con_defs.append('{ltable}:"{lfield}" -> {rtable}_{sheet}:{rfield};'.format(ltable=ltable, lfield=lfield, rtable=rtable, sheet=sheet, rfield=rfield))

con_defs


Out[9]:
['get_building_air_conditioning:"type_cs" -> get_database_air_conditioning_systems_COOLING:code;',
 'get_building_air_conditioning:"type_ctrl" -> get_database_air_conditioning_systems_CONTROLLER:code;',
 'get_building_typology:"STANDARD" -> get_database_construction_standards_STANDARD_DEFINITION:STANDARD;',
 'get_building_typology:"2ND_USE" -> get_database_use_types_properties_INTERNAL_LOADS:code;',
 'get_building_air_conditioning:"type_dhw" -> get_database_air_conditioning_systems_HOT_WATER:code;',
 'get_building_air_conditioning:"type_vent" -> get_database_air_conditioning_systems_VENTILATION:code;',
 'get_building_architecture:"type_leak" -> get_database_envelope_systems_TIGHTNESS:code;',
 'get_building_architecture:"type_cons" -> get_database_envelope_systems_CONSTRUCTION:code;',
 'get_building_architecture:"type_base" -> get_database_envelope_systems_FLOOR:code;',
 'get_building_supply:"type_dhw" -> get_database_supply_assemblies_HOT_WATER:code;',
 'get_building_air_conditioning:"type_hs" -> get_database_air_conditioning_systems_HEATING:code;',
 'get_building_architecture:"type_floor" -> get_database_envelope_systems_FLOOR:code;',
 'get_building_architecture:"type_win" -> get_database_envelope_systems_WINDOW:code;',
 'get_building_architecture:"type_wall" -> get_database_envelope_systems_WALL:code;',
 'get_building_supply:"type_el" -> get_database_supply_assemblies_ELECTRICITY:code;',
 'get_building_typology:"1ST_USE" -> get_database_use_types_properties_INTERNAL_LOADS:code;',
 'get_building_supply:"type_cs" -> get_database_supply_assemblies_COOLING:code;',
 'get_building_typology:"3RD_USE" -> get_database_use_types_properties_INTERNAL_LOADS:code;',
 'get_building_architecture:"type_roof" -> get_database_envelope_systems_ROOF:code;',
 'get_building_architecture:"type_shade" -> get_database_envelope_systems_SHADING:code;',
 'get_building_supply:"type_hs" -> get_database_supply_assemblies_HEATING:code;']

In [10]:
diagram_template = """
/* this diagram was generated by notebooks/2020.02.25-create-tables-entity-relationship-diagram.ipynb 
   you can preview it in VSCode with the "Graphviz Preview" extension.
*/
digraph tables_diagram {

    graph [pad="0.5", nodesep="0.5", ranksep="2"];
    node [shape=plain];
    rankdir=LR;
    
{% for table in tables %}
   {{table}}
{% endfor %}

{% for db in dbs %}
    {{db}}
{% endfor %}

{% for con in cons %}
    {{con}}
{% endfor %}
}
"""


with open(OUTPUT_PATH, 'w') as fp:
    fp.write(Template(diagram_template).render(tables=table_defs, dbs=db_defs, cons=con_defs))