3. Register Entities
Registering entities represented in grocery dataset¶
In FeatureByte, an "entity" models real-world objects and ideas. These entities often correspond to columns in database tables.
Taking our grocery scenario as an example, we can view "Customer", "Invoice", and "Item" as entities.
To help FeatureByte identify these entities in the data and the columns that represent them, we'll be creating and tagging these entities in this tutorial.
import featurebyte as fb
# Set your profile to the tutorial environment
fb.use_profile("tutorial")
catalog_name = "Grocery Dataset Tutorial"
catalog = fb.Catalog.activate(catalog_name)
16:05:47 | WARNING | Service endpoint is inaccessible: http://featurebyte-server:8088 16:05:47 | INFO | Using profile: tutorial 16:05:47 | INFO | Using configuration file at: /Users/gxav/.featurebyte/config.yaml 16:05:47 | INFO | Active profile: tutorial (https://tutorials.featurebyte.com/api/v1) 16:05:47 | WARNING | Remote SDK version (1.1.0.dev7) is different from local (1.1.0.dev1). Update local SDK to avoid unexpected behavior. 16:05:47 | INFO | No catalog activated. 16:05:47 | INFO | Catalog activated: Grocery Dataset Tutorial
As previously discussed, we'll establish the following entities:
- customer - an individual shopping at the stores
- invoice - a record of the customer's purchase
- item - individual items on the invoice
- product - products available in the store for purchase
- productgroup - the category or group a product falls under
- frenchstate - a region in France (since our dataset revolves around French grocery stores and their customers)
It's worth noting that the count of entities doesn't necessarily have to align with the number of tables. An entity is a business-oriented term, and multiple entities might be represented within a single table.
When creating an entity, you'll need to define its serving name. This name acts as a unique identifier, particularly during preview or serving requests.
catalog.create_entity(name="customer", serving_names=["GROCERYCUSTOMERGUID"])
catalog.create_entity(name="invoice", serving_names=["GROCERYINVOICEGUID"])
catalog.create_entity(name="item", serving_names=["GROCERYINVOICEITEMGUID"])
catalog.create_entity(name="product", serving_names=["GROCERYPRODUCTGUID"])
catalog.create_entity(name="productgroup", serving_names=["PRODUCTGROUP"])
catalog.create_entity(name="frenchstate", serving_names=["FRENCHSTATE"])
name | frenchstate |
created_at | 2024-06-12 08:05:48 |
updated_at | None |
description | None |
serving_names | ['FRENCHSTATE'] |
catalog_name | Grocery Dataset Tutorial |
Now that we've established the entities, it's time to guide FeatureByte in mapping these entities to the actual data in our tables.
customer_table = catalog.get_table("GROCERYCUSTOMER")
invoice_table = catalog.get_table("GROCERYINVOICE")
items_table = catalog.get_table("INVOICEITEMS")
product_table = catalog.get_table("GROCERYPRODUCT")
# tag the entities for the grocery customer table
customer_table.GroceryCustomerGuid.as_entity("customer")
customer_table.State.as_entity("frenchstate")
# tag the entities for the grocery invoice table
invoice_table.GroceryInvoiceGuid.as_entity("invoice")
invoice_table.GroceryCustomerGuid.as_entity("customer")
# tag the entities for the grocery items table
items_table.GroceryInvoiceItemGuid.as_entity("item")
items_table.GroceryInvoiceGuid.as_entity("invoice")
items_table.GroceryProductGuid.as_entity("product")
# tag the entities for the grocery product table
product_table.GroceryProductGuid.as_entity("product")
product_table.ProductGroup.as_entity("productgroup")
Now, if we list the tables as we did in the previous tutorial, we'll notice that entities have been assigned to each table.
display(catalog.list_tables())
id | name | type | status | entities | created_at | |
---|---|---|---|---|---|---|
0 | 666956c78080c62d0dc616e2 | GROCERYPRODUCT | dimension_table | PUBLIC_DRAFT | [product, productgroup] | 2024-06-12T08:05:27.992000 |
1 | 666956c58080c62d0dc616e1 | INVOICEITEMS | item_table | PUBLIC_DRAFT | [item, invoice, product] | 2024-06-12T08:05:26.172000 |
2 | 666956c38080c62d0dc616e0 | GROCERYINVOICE | event_table | PUBLIC_DRAFT | [invoice, customer] | 2024-06-12T08:05:24.205000 |
3 | 666956c28080c62d0dc616df | GROCERYCUSTOMER | scd_table | PUBLIC_DRAFT | [customer, frenchstate] | 2024-06-12T08:05:22.270000 |
We can also list entities separately:
display(catalog.list_entities())
id | name | serving_names | created_at | |
---|---|---|---|---|
0 | 666956dc09f6984daf191c96 | frenchstate | [FRENCHSTATE] | 2024-06-12T08:05:48.452000 |
1 | 666956dc09f6984daf191c95 | productgroup | [PRODUCTGROUP] | 2024-06-12T08:05:48.244000 |
2 | 666956db09f6984daf191c94 | product | [GROCERYPRODUCTGUID] | 2024-06-12T08:05:48.032000 |
3 | 666956db09f6984daf191c93 | item | [GROCERYINVOICEITEMGUID] | 2024-06-12T08:05:47.823000 |
4 | 666956db09f6984daf191c92 | invoice | [GROCERYINVOICEGUID] | 2024-06-12T08:05:47.625000 |
5 | 666956db09f6984daf191c91 | customer | [GROCERYCUSTOMERGUID] | 2024-06-12T08:05:47.417000 |
And let's examine the relationships between entities, which FeatureByte has conveniently outlined for us:
display(catalog.list_relationships())
id | relationship_type | entity | related_entity | relation_table | relation_table_type | enabled | created_at | updated_at | |
---|---|---|---|---|---|---|---|---|---|
0 | 666956dfddd5be620a410f78 | child_parent | product | productgroup | GROCERYPRODUCT | dimension_table | True | 2024-06-12T08:05:51.721000 | None |
1 | 666956df4deaed1e05217b70 | child_parent | item | product | INVOICEITEMS | item_table | True | 2024-06-12T08:05:51.218000 | None |
2 | 666956deec7bc32effdab779 | child_parent | item | invoice | INVOICEITEMS | item_table | True | 2024-06-12T08:05:51.003000 | None |
3 | 666956deec7bc32effdab774 | child_parent | invoice | customer | GROCERYINVOICE | event_table | True | 2024-06-12T08:05:50.525000 | None |
4 | 666956deddd5be620a410f70 | child_parent | customer | frenchstate | GROCERYCUSTOMER | scd_table | True | 2024-06-12T08:05:50.038000 | None |