Skip to content

Support for composite business keys #17

@leo-schick

Description

@leo-schick

I use several times composite business keys in addition to a surrogate keys. Sample dimensional table:

CREATE TABLE vendor
(
    id INTEGER IDENTITY(1,1) NOT NULL,
    company_num VARCHAR(5) NOT NULL,
    account_num VARCHAR(20) NOT NULL,

    name TEXT,
    street TEXT,

    PRIMARY KEY (id),
    UNIQUE (company_num, account_num)
)

My fact table often only includes the business key but not the surrogate key:

CREATE TABLE purchase_transaction
(
    company_num VARCHAR(5) NOT NULL,
    vendor_order_account_num VARCHAR(20) NOT NULL,
    vendor_invoice_account_num VARCHAR(20) NOT NULL,

    invoice_date DATE,

    product_num VARCHAR(20),
    net_line_amount_acy DECIMAL(32,5),
    net_line_discount_acy DECIMAL(32,5)
)

The mara_schema module currently only supports relationships where the foreign key is related to the primary key (which is unique). So I have to manually add a vendor_order_account_fk to purchase_transaction and use an UPDATE SQL statement to set the foreign key based on the business key connection.

It would be great when mara_schema would support the following use cases:

  1. use the business key instead of the primary key and/or
  2. generate SQL statements to update a foreign key related based on the primary key

Option 1: Using the business key in relations

Required changes:

  1. The entity would need the option to define a business key (bk_column_names in Entity.__init__), `Entity.
  2. The Entity.link_entity method would need a new parameter bk_columns.
  3. The mara_schema.sql_generation.data_set_sql_query would need to use the business key in the LEFT JOIN when the primary key is not defined.

Option 2: Gelerating an update statement

Required changes:

  1. Add a function to generate an SQL statement setting a foreign key property based on the business key. It should generate something similar to:
UPDATE purchase_transaction
SET purchase_transaction.vendor_order_account_fk = vendor.id
FROM purchase_transaction
INNER JOIN vendor ON
    vendor.company_num = purchase_transaction.company_num AND
    vendor.account_num = purchase_transaction.vendor_order_account_num
WHERE purchase_transaction.vendor_order_account_fk IS NULL
  1. add a function to generate the SQL statements for all relations for multiple/all defined entities
  2. (option) maybe adding the option to add the foreign key column to the fact table as well.
ALTER TABLE purchase_transaction ADD COLUMN IF NOT EXISTS vendor_order_account_fk INTEGER;

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions