How to add multiple relationships to a new entity? - featuretools

I am trying to add multiple relationships simultaneously to an entityset that i created. I use the following code:
import featuretools as ft
data = ft.demo.load_mock_customer()
customers_df = data["customers"]
sessions_df = data["sessions"]
transactions_df = data["transactions"]
entities = {
"customers" : (customers_df, "customer_id"),
"sessions" : (sessions_df, "session_id", "session_start"),
"transactions" : (transactions_df, "transaction_id", "transaction_time")}
es = ft.EntitySet('es',entities=entities)
relationships = [("sessions", "session_id", "transactions", "session_id"),
("customers", "customer_id", "sessions", "customer_id")]
es.add_relationships(relationships)
It throws AttributeError: 'tuple' object has no attribute 'child_entity'. Is this way to add multiple entities to an entityset correct (i think it is correct if i am reading the official doc correctly) or am i missing something?

The input to add_relationships must be a list of relationship objects. This is how you would add the relationships to the entity set:
relationships = []
parent = es["sessions"]["session_id"]
child = es["transactions"]["session_id"]
relationship = ft.Relationship(parent, child)
relationships.append(relationship)
parent = es["customers"]["customer_id"]
child = es["sessions"]["customer_id"]
relationship = ft.Relationship(parent, child)
relationships.append(relationship)
es.add_relationships(relationships)
As an alternative, you can directly construct an entity set with the relationships.
relationships = [(
"sessions",
"session_id",
"transactions",
"session_id",
), (
"customers",
"customer_id",
"sessions",
"customer_id",
)]
es = ft.EntitySet(
id='es',
entities=entities,
relationships=relationships,
)
Let me know if this helps.

Related

Merging complex types

I'm struggling with merging maps that have duplicate keys, since the built-in merge function will only keep the latest argument that has matching keys or attributes.
My maps are of the following shape:
{mykey = ["item1","item2","item3"]}
{mykey = ["item4","item5","item6"]}
The merge function simply returns {mykey = ["item4","item5","item6"]} (or whatever is the last argument). I'd like to compose a map like
{mykey = ["item1","item2","item3","item4","item5","item6"]}
I don't believe there's a function I can use to achieve this. However, I suspect that a for loop is the right approach, yet my knowledge is failing me.
Hi #MattSchuchard, thanks for your help. The parent map structure (if I am following you correctly), is a local variable. I am using keys and values from this local in order to retrieve object_ids from the azuread_users and azuread_groups data sources. My locals looks like this:
locals {
roles = {
role1 = {
users = ["user1#domain.com","user2#domain.com"]
groups = ["myGroup1","myGroup2"]
}
}
I am referencing this local in the data sources as follows:
data azuread_users.lookup {
for_each = local.roles
user_principal_names = each.values.users
}
data azuread_groups.lookup {
for_each = local.roles
display_names = each.values.groups
}
These data sources export object_ids as an attribute (which I will then use when adding members to groups in a resource block). The exported attributes are in the shape detailed in my original post.
I would like to compose a combined list of all object_ids exported from both data.azuread_users.lookup and data.azuread_groups.lookup which I can then provide as an argument when creating a group:
resource "azuread_group" "my_group" {
members = $myCombinedListOfObjectIDs
}
Depending on whether you want a list/map you can use this:
locals {
input = { mykey = ["item1", "item2", "item3"] }
input2 = { mykey = ["item4", "item5", "item6"] }
merged = concat(local.input.mykey, local.input2.mykey)
merged_mykey = {
mykeys = concat(local.input.mykey, local.input2.mykey)
}
}
The output is
> local.merged_mykey
{
"mykeys" = [
"item1",
"item2",
"item3",
"item4",
"item5",
"item6",
]
}
> local.merged
[
"item1",
"item2",
"item3",
"item4",
"item5",
"item6",
]
If you're worried about duplicates you can wrap it in a distinct call. https://www.terraform.io/language/functions/distinct

Restkit + Core Data: Inserts duplicate values in a UITableView on every app launch

Following AlexEdge Tutorial I have encountered the following behavior. I can provide code as requested since there are many lines and I'm not really sure where to look. Basically, it "works" in the sense that the data is properly loaded into the UITableView, but after stopping and starting up the simulator, it inserts new duplicate rows in each section.
I figured this would have something to do with caching but I am following the above tutorial pretty closely and I've set the identificationAttributes to identify unique records (wouldn't, for example, adding ALL attributes effectively eliminate the possibility that I've not specified a sufficiently unique key, just for debugging purposes?). I've tried changing the Cache name, setting it nil, but it keeps inserting duplicates. Every so often I reset the simulator just to start on a clean slate.
If it matters, I am calling getObjectsAtPath in viewDidLoad as per the tutorial. My understanding of how RestKit worked was that it was okay to do so because it would be smart enough to infer that no updates were necessary as the records are all the same.
Edit
I have set identificationAttributes to an array of two integer attributes that really do determine a unique record.
I also have a managedObjectCache:
// Seal the deal
[managedStore createPersistentStoreCoordinator];
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:#"CCTDB.sqlite"];
NSError *error;
NSPersistentStore *persistentStore =
[managedStore
addSQLitePersistentStoreAtPath:storePath
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:#{
NSMigratePersistentStoresAutomaticallyOption:#YES,
NSInferMappingModelAutomaticallyOption:#YES
}
error:&error];
NSAssert(persistentStore, #"Failed to add persistent store with error: %#", error);
[managedStore createManagedObjectContexts];
managedStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedStore.persistentStoreManagedObjectContext];
EDIT 1
Here is the log output of the second time around
(2013-07-11 03:18:29.961 cocoaclinical[18773:3d07] D restkit.object_mapping:RKPropertyInspector.m:130 Cached property inspection for Class 'EMDisease': {
diseaseId = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = diseaseId;
};
diseaseIdValue = {
isPrimitive = 1;
keyValueCodingClass = NSNumber;
name = diseaseIdValue;
};
name = {
isPrimitive = 0;
keyValueCodingClass = NSString;
name = name;
};
subDiseaseId = {
isPrimitive = 0;
keyValueCodingClass = NSNumber;
name = subDiseaseId;
};
subDiseaseIdValue = {
isPrimitive = 1;
keyValueCodingClass = NSNumber;
name = subDiseaseIdValue;
};
}
2013-07-11 03:18:29.975 cocoaclinical[18773:3f03] I restkit.core_data:RKInMemoryManagedObjectCache.m:94 Caching instances of Entity 'EMDisease' by attributes 'diseaseId, subDiseaseId'
2013-07-11 03:18:29.983 cocoaclinical[18773:3f03] T restkit.core_data:RKInMemoryManagedObjectCache.m:127 Cached 31 objects
2013-07-11 03:18:29.984 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMapperOperation.m:231 Asked to map source object {
DiseaseSystemIdMember = 161;
DisplayNameMember = "Acute Lymphocytic Leukemia";
SubDiseaseSystemIdMember = 1886;
} with mapping <RKEntityMapping:0x96c2850 objectClass=EMDisease propertyMappings=(
"<RKAttributeMapping: 0x96ba060 SubDiseaseSystemIdMember => subDiseaseId>",
"<RKAttributeMapping: 0xb58df40 DisplayNameMember => name>",
"<RKAttributeMapping: 0xb58df70 DiseaseSystemIdMember => diseaseId>"
)>
2013-07-11 03:18:29.984 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMappingOperation.m:952 Starting mapping operation...
2013-07-11 03:18:29.985 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:953 Performing mapping operation: <RKMappingOperation 0xb5b7820> for 'EMDisease' object. Mapping values from object {
DiseaseSystemIdMember = 161;
DisplayNameMember = "Acute Lymphocytic Leukemia";
SubDiseaseSystemIdMember = 1886;
} to object <EMDisease: 0xb5b7ee0> (entity: EMDisease; id: 0xb5b7f80 <x-coredata:///EMDisease/t8DD8EE18-C798-468F-9E03-C6A3C724AA772> ; data: {
diseaseId = 161;
name = nil;
subDiseaseId = 1886;
}) with object mapping (null)
2013-07-11 03:18:30.027 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'SubDiseaseSystemIdMember' to 'subDiseaseId'
2013-07-11 03:18:30.028 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:583 Skipped mapping of attribute value from keyPath 'SubDiseaseSystemIdMember to keyPath 'subDiseaseId' -- value is unchanged (1886)
2013-07-11 03:18:30.029 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'DisplayNameMember' to 'name'
2013-07-11 03:18:30.029 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:572 Mapped attribute value from keyPath 'DisplayNameMember' to 'name'. Value: Acute Lymphocytic Leukemia
2013-07-11 03:18:30.030 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:550 Mapping attribute value keyPath 'DiseaseSystemIdMember' to 'diseaseId'
2013-07-11 03:18:30.030 cocoaclinical[18773:3f03] T restkit.object_mapping:RKMappingOperation.m:583 Skipped mapping of attribute value from keyPath 'DiseaseSystemIdMember to keyPath 'diseaseId' -- value is unchanged (161)
2013-07-11 03:18:30.031 cocoaclinical[18773:3f03] D restkit.object_mapping:RKMappingOperation.m:1021 Finished mapping operation successfully...
You do need to set identificationAttributes, generally only one or two attributes though, not everything. Your entities should have some unique identifier.
You also want to add a managedObjectCache to your managed object store. This is the part that allows RestKit to match objects using your identificationAttributes and update the existing items instead of creating new ones.

How Can I Join On Two Columns with a LinkEntity in CRM 2011?

I am using a Link Entity to join a two entities:
LinkEntity pricelevelentity = new LinkEntity();
pricelevelentity.JoinOperator = JoinOperator.Inner;
pricelevelentity.LinkFromEntityName = "product";
pricelevelentity.LinkFromAttributeName = "productid";
pricelevelentity.LinkToEntityName = "productpricelevel";
pricelevelentity.LinkToAttributeName = "productid";
query.LinkEntities.Add(pricelevelentity);
The above is joining Product and ProductPriceLevel on the ProductId attribute. I also want to add to the join Product.uomid on ProductPriceLevel.DefaultUomId
How can i do this?
If you are attempting to return a column for a linked/joined entity to be able to perform additional filtering on the client side, LinkEntity has a Column property you should use, for example:
new QueryExpression("product")
{
ColumnSet = new ColumnSet("oumid"),
LinkEntities =
{
new LinkEntity("product", "productpricelevel", "productid", "productid", JoinOperator.Inner)
{
Columns = new ColumnSet("defaultuomid")
}
}
};
Not sure how James's answer was marked as the answer, but you can not join on more than one column using a linked entity. You can use James's answer to return both values, and perform a join on the client side though, but CRM doesn't support this type of Join:
Select * FROM A INNER JOIN B ON A.OneId = B.OneId AND A.TwoId = B.TwoId
If you know the value of the Product's UomId, you can add it to a where clause though:
var qe = new QueryExpression("product");
var productPriceLevel = new LinkEntity("product", "productpricelevel", "productid", "productid", JoinOperator.Inner);
qe.LinkEntities = productPriceLevel;
productPriceLevel.LinkCriteria.AddCondition("defaultuomid", ConditionOperator.Equal, product.UomId);
Which would effectively look like this:
Select * FROM A INNER JOIN B ON A.OneId = B.OneId AND B.TwoId = 10 -- the Value of whatever the single A.TwoId value is you're looking for.

Dynamics CRM 2011 - Getting too many rows back from a retrievemultiple on salesordersdetail

I have a plugin that is registered Update, Order, Post Operation. In the plugin I perform a retrievemultiple on the salesorderdetail. The problem I'm having is that there are 3 products that make up the order but I am returning 5 rows from the retrieve operation. I have added and deleted the same product multiple times during my testing and I'm not sure if that's what's causing the problem. I was thinking that after deleting a product from the order it may set a flag and get deleted after, but I don't see a status code or state code as an attribute. Why would it return too many rows?
Here is my code...
// Set the properties of the QueryExpression object.
orderDetailQuery.EntityName = "salesorderdetail";
orderDetailQuery.ColumnSet = orderDetailColumnSet;
EntityCollection salesOrderDetail = service.RetrieveMultiple(orderDetailQuery);
orderProductQuery.EntityName = "product";
orderProductQuery.ColumnSet = orderProductColumnSet;
foreach (var orderDetail in salesOrderDetail.Entities)
{
if(orderDetail.Attributes.Contains("productid"))
{
productGuid = ((EntityReference)orderDetail["productid"]).Id;
Entity product = service.Retrieve("product", productGuid, orderProductColumnSet);
}
}
Thank you for the help!!
The code you posted does not show you filtering for the specific Order.
I would expect that to retrieve all entities of that type in the system.
To filter, assuming you are using a QueryByAttribute, is to add an filter along the lines of:
var query = new QueryByAttribute();
query.EntityName = "salesorderdetail";
query.AddAttributeValue("orderid", orderId);//orderId is the Id of the parent Order
orderDetailQuery.EntityName = "salesorderdetail";
orderDetailQuery.ColumnSet = orderDetailColumnSet;
var results = service.RetrieveMultiple(query);
That way you are restricting your query to just products for the given order.
I'm not sure that your filtering is implemented. Here's a shot from the hip on how you could query for instances of SalesOrderDetail entity, fetching the values of fieldName1 and fieldName2 fields provided that the it's linked to the order with guid orderId.
QueryExpression query = new QueryExpression
{
EntityName = "salesorderdetail",
ColumnSet = new ColumnSet("fieldName1", "fieldName2"),
Criteria = new FilterExpression
{
Conditions =
{
new ConditionExpression
{
AttributeName = "orderid",
Operator = ConditionOperator.Equal,
Values = { orderId }
}
}
}
};

populate a comboBox in Griffon App dynamically

I have 2 comboBoxes in my View of Griffon App (or groovy swingBuilder)
country = comboBox(items:country(), selectedItem: bind(target:model, 'country',
value:model.country), actionPerformed: controller.getStates)
state = comboBox(items:bind(source:model, sourceProperty:'states'),
selectedItem: bind(target:model, 'state', value:model.state))
The getStates() in the controller, populates #Bindable List states = [] in the model based on the country selected.
The above code doesn't give any errors, but the states are never populated.
I changed the states from being List to a range object(dummy), it gives me an error MissingPropertyException No such property items for class java.swing.JComboBox.
Am I missing something here? There are a couple of entries related to this on Nabble but nothing is clear. The above code works if I had a label instead of a second comboBox.
I believe that the items: property is not observable and it's only used while the node is being built. You may have better results by setting the binding on the model or by using GlazedLists' EventList.
Model:
#Bindable String country = ""
EventList statesList = new BasicEventList()
Controller:
def showStates = { evt = null ->
model.statesList.clear()
def states = []
if(model.country == "US")
states = ["CA","TX", "CO", "VA"]
else if(model.country == "Canada")
states = ["BC", "AL"]
else
states = ["None"]
edt {model.statesList.addAll(states.collect{it})}
}
View:
def createComboBoxStatesModel() {
new EventComboBoxModel(model.daysList) }
comboBox( items:["USA","Canada","other"], selectedItem: bind(target:model, 'country', value: model.country), actionPerformed : controller.showStates)
comboBox( model: createComboBoxStatesModel(), selectedItem: bind(target:model, 'state', value:model.state))

Resources