3. Build Logical Data Model

Next, you will connect your workspace to your data source. During this connection, you create a logical data model (LDM), which serves as a layer of abstraction over the database structure.

The LDM simplifies data management by allowing easy updates to data structures, such as renaming a database column, without disrupting your analytics. It also curates what end-users see, ensuring they access only the most relevant and valid data combinations. This streamlines analytics processes and maintains data integrity across changes.

UI
API

Steps:

  1. In Workspaces, on your newly created workspace, click on Connect data.

    Screenshot of the Workspace page.

    You will be redirected to the Data tab inside the workspace which is where you choose which data source to connect to, and where you build the LDM for the data source.

  2. Ensure the workspace is connected to your data source, select all tables from your database and click Add selected.

    Screenshot of the Data tab of a workspace showing the logical data modeler.

    The LDM is populated with datasets and their relationships based on the structure of the connected database.

  3. Click Save.

    Screenshot of the Data tab of a workspace showing the logical data modeler with populated datasets.

    The model is finished and your database is now connected to your workspace.

    Screenshot of the Data tab of a workspace showing the finalized logical data model.

Once you create a LDM, you can use the GoodData API to work with it:

curl $HOST_URL/api/v1/layout/workspaces/$WORKSPACE_ID/logicalModel \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer <API_TOKEN>" \
  -X GET \
  | jq .

You will get a similar response (with your LDM):

{
  "ldm": {
    "datasets": [
      {
        "attributes": [
          {
            "defaultView": {
              "id": "label_id",
              "type": "label"
            },
            "description": "Customer name including first and last name.",
            "id": "attr.customers.customer_name",
            "labels": [
              {
                "description": "Customer name",
                "id": "label.customer_name",
                "sourceColumn": "customer_name",
                "sourceColumnDataType": "STRING",
                "tags": [
                  "Customers"
                ],
                "title": "Customer name",
                "valueType": "\"TEXT\" | \"HYPERLINK\" | \"GEO\""
              }
            ],
            "sortColumn": "customer_name",
            "sortDirection": "\"ASC\" | \"DESC\"",
            "sourceColumn": "customer_name",
            "sourceColumnDataType": "STRING",
            "tags": [
              "Customers"
            ],
            "title": "Customer Name"
          }
        ],
        "dataSourceTableId": {
          "dataSourceId": "my-postgres",
          "path": ["postgres_demo_3920fbd8f33ec386", "campaign_channels"],
          "id": "customers",
          "type": "DATA_SOURCE"
        },
        "description": "Our customers.",
        "facts": [
          {
            "description": "A number of orders created by the customer - including all orders, even the non-delivered ones.",
            "id": "fact.customer_order_count",
            "sourceColumn": "customer_order_count",
            "sourceColumnDataType": "STRING",
            "tags": [
              "Customers"
            ],
            "title": "Customer order count"
          }
        ],
        "grain": [
          {
            "id": "attr.customers.customer_name",
            "type": "ATTRIBUTE"
          }
        ],
        "id": "customers",
        "references": [
          {
            "identifier": {
              "id": "customers",
              "type": "DATASET"
            },
            "multivalue": false,
            "sourceColumns": [
              "customer_id"
            ]
          }
        ],
        "tags": [
          "Customers"
        ],
        "title": "Customers"
      }
    ],
    "dateInstances": [
      {
        "description": "A customer's order date",
        "granularities": [
          "MINUTE"
        ],
        "granularitiesFormatting": {
          "titleBase": "string",
          "titlePattern": "%titleBase - %granularityTitle"
        },
        "id": "date",
        "tags": [
          "Customer dates"
        ],
        "title": "Date"
      }
    ]
  }
}