Power Query: Structured record while converting to JSON - powerbi

I have a power query record as follows:
Data = [
tracker = {
[
foo = {
[
field_a= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data"
],
[
foo = {
[
field_c= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data2"
]
}
]
When I convert it into a JSON, I obtain this:
{
"tracker": [
{
"foo": [
{
"field_a": "Something",
"field_b": "data2"
},
{
"field_a": "Something",
"field_c": "data2"
}
],
"bar": "Data"
},
{
"foo": [
{
"field_c": "Something",
"field_b": "data2"
},
{
"field_a": "Something",
"field_c": "data2"
}
],
"bar": "Data2"
}
]
}
I need the foo array to have structured objects within it, in the sense that each object should have field_a, field_b, field_c in it. Example:
foo = {
[
field_c= "Something",
field_b = "data2",
field_a = null
],
[
field_a= "Something",
field_c = "data2".
field_b = null
]
}
I tried using
List.Transform(x, each Record.TransformFields(_, {
{ "field_a", Text.Trim },
{ "field_b", Text.Trim },
{ "field_c", Text.Trim }
}, MissingField.UseNull))
however, I am losing reference to the bar field in the final output. Any help would be appreciated.

This seems to work for me.
let
Data = [
tracker = {
[
foo = {
[
field_a= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data"
],
[
foo = {
[
field_c= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data2"
]
}
],
#"Converted to Table" = Record.ToTable(Data),
#"Added Custom" = Table.AddColumn(#"Converted to Table", "Custom",
each let
a = [Value],
b = List.Transform(a, each Record.TransformFields(_, {
{ "foo", (x)=> List.Transform(x, (y)=> Record.TransformFields(y, {
{ "field_a", Text.Trim },
{ "field_b", Text.Trim },
{ "field_c", Text.Trim }
}, MissingField.UseNull) )}
}))
in b)
in
#"Added Custom"

Try this in powerquery
It splits on } then checks for the fields defined in the first row, and if one or two of them are missing, adds them, then puts the pieces back together
let TableWithPhrases = Table.Buffer(#table({"Keyword"}, {{"field_a"}, {"field_b"}, {"field_c"}})),
Source = [tracker = {[foo = {[
field_a= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data"
],
[
foo2 = {
[
field_c= "Something",
field_b = "data2"
],
[
field_a= "Something",
field_c = "data2"
]
},
bar = "Data2"
]
}
],
prior =Text.FromBinary(Json.FromValue(Source[tracker])),
Splitit=Text.Split(prior,"}"),
#"Converted to Table" = Table.FromList(Splitit, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Changed Type" = Table.TransformColumnTypes(#"Converted to Table",{{"Column1", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each List.Select(TableWithPhrases[Keyword], (x) => not(Text.Contains([Column1], x)))),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "Custom.1", each if List.Count([Custom])=Table.RowCount(TableWithPhrases) then "" else Text.Combine(List.Transform([Custom], each ","""&_&""":"""""))),
#"Added Custom2" = Table.AddColumn(#"Added Custom1", "Custom.2", each [Column1]&[Custom.1]),
final = Text.Combine(#"Added Custom2"[Custom.2],"}")
in final
Before
[{"foo":[{"field_a":"Something","field_b":"data2"},{"field_a":"Something","field_c":"data2"}],"bar":"Data"},{"foo2":[{"field_c":"Something","field_b":"data2"},{"field_a":"Something","field_c":"data2"}],"bar":"Data2"}]
After
[{"foo":[{"field_a":"Something","field_b":"data2","field_c":""},{"field_a":"Something","field_c":"data2","field_b":""}],"bar":"Data"},{"foo2":[{"field_c":"Something","field_b":"data2","field_a":""},{"field_a":"Something","field_c":"data2","field_b":""}],"bar":"Data2"}]

Related

Power query losing reference to the parent record after updating child/nested record

I have the following record:
Source = [
Properties = [
steps = {
[
index = {
[
display = "Something",
data = "data2"
]
},
access = "Column1"
],
[
indices = {
[
display = "Something else",
data = "data2"
]
},
access = "Column2"
]
},
opt = [
key1 = "val1",
key2 = "val2",
key3 = "val3"
]
]
]
I am updating/adding a new field inside the nested record. However, after that I am unable to get the reference to the original record with the modified field.
Here is the M code for the change. I am adding a new field updatedKey3 which contained the capitalized key3 field and then I am removing the key3.
let Source = [
Properties = [
steps = {
[
index = {
[
display = "Something",
data = "data2"
]
},
access = "Column1"
],
[
indices = {
[
display = "Something else",
data = "data2"
]
},
access = "Column2"
]
},
opt = [
key1 = "val1",
key2 = "val2",
key3 = "val3"
]
]
],
step1 = Source[Properties][opt],
step2 = Record.AddField(step1, "updatedKey3", Text.Upper(step1[key3])),
step3 = Record.RemoveFields(step2, {"key3"})
in
step3
step3 returns the record:
[key1 = "val1", key2 = "val2", updatedKey3 = "VAL3"]
However I want this change within the Source record and view it completely. Any help would be appreciated.
I was able to do it by adding, removing and renaming fields. The following is the updated code for it. If anyone has a more optimized way to do so, please let me know.
let Source = [
Properties = [
steps = {
[
index = {
[
display = "Something",
data = "data2"
]
},
access = "Column1"
],
[
indices = {
[
display = "Something else",
data = "data2"
]
},
access = "Column2"
]
},
opt = [
key1 = "val1",
key2 = "val2",
key3 = "val3"
]
]
],
step1 = Source,
step2 = Record.RenameFields(Record.RemoveFields(Record.AddField(step1[Properties][opt], "tmpKey", Text.Upper(step1[Properties][opt][key3])), "key3"), {"tmpKey", "key3"}),
step3 = Record.RenameFields(Record.RemoveFields(Record.AddField(step1[Properties], "tmpOpt", step2), "opt"), {"tmpOpt", "opt"}),
step4 = Record.RenameFields(Record.RemoveFields(Record.AddField(step1, "tmpProperties", step3), "Properties"), {"tmpProperties", "Properties"})
in
step4

How to set dynamic attributes in django rest framework serializers?

I have some json in the following format:
{
"daySchedules": {
"500000004061582000": {
"scheduleName": "Friday-Sunday",
"services": [
{
"name": "Lunch",
"hours": {
"startTime": "12:00:00.000",
"endTime": "16:00:00.000"
},
"overnight": false
},
{
"name": "Dinner",
"hours": {
"startTime": "17:00:00.000",
"endTime": "23:00:00.000"
},
"overnight": false
}
],
"openTime": "12:00:00.000",
"closeTime": "23:00:00.000"
},
"500000004061559163": {
"scheduleName": "Tuesday-Thursday",
"services": [
{
"name": "Breakfast",
"hours": {
"startTime": "04:00:00.000",
"endTime": "11:00:00.000"
},
"overnight": false
},
{
"name": "Lunch",
"hours": {
"startTime": "12:00:00.000",
"endTime": "16:00:00.000"
},
"overnight": false
},
{
"name": "Dinner",
"hours": {
"startTime": "17:00:00.000",
"endTime": "20:00:00.000"
},
"overnight": false
}
],
"openTime": "04:00:00.000",
"closeTime": "20:00:00.000"
}
},
"weekSchedule": {
"monday": null,
"tuesday": "500000004061559163",
"wednesday": "500000004061559163",
"thursday": "500000004061559163",
"friday": "500000004061582000",
"saturday": "500000004061582000",
"sunday": "500000004061582000"
}
}
The attributes in the json 500000004061582000 and 500000004061559163 is dynamic and determined by what's returned in the weekSchedule.
I wish to create the following serializers:
class ScheduleForDaySerializer(serializers.Serializer):
schedule_name = serializers.CharField()
services = serializers.ListField()
open_time = serializers.CharField()
close_time = serializers.CharField()
class WeekScheduleSerializer(serializers.Serializer):
monday = serializers.CharField(allow_null=True)
tuesday = serializers.CharField(allow_null=True)
wednesday = serializers.CharField(allow_null=True)
thursday = serializers.CharField(allow_null=True)
friday = serializers.CharField(allow_null=True)
saturday = serializers.CharField(allow_null=True)
sunday = serializers.CharField(allow_null=True)
class DaySchedulesSerializer(serializers.Serializer):
# what comes here?
class SchedulesSerializer(serializers.Serializer):
day_schedules = DaySchedulesSerializer()
week_schedule = WeekScheduleSerializer()
I'm struggling to determine how to serialize the attributes for that daySchedules json object since the key attributes are dynamic and not necessarily the same each time. Ideally I want to explicitly list out what each attribute type is.
After creating the serializer I want to do the following:
serializer = SchedulesSerializer(data=data) # data is the json object shown above
serializer.is_valid()
response = serializer.data
# do something with the response

Power Query M. Json array of key-pair transform in Column

Thanks for your help,
I'm trying to transform the Array called 'Tags' hosting a list of pair of key-values into a list of columns: CustomerId, CustomerDisplayName, CustomerPath where each list contains a respective value being a store for each charge.
{
"periodFrom": "2020-11-09T00:00:00",
"periodTo": "2020-12-08T00:00:00",
"charges": [
{
"listPrice": 5.05,
"netPrice": 5.05,
"netPriceProrated": 5.05,
"subTotal": 5.05,
"currency": "CAD",
"isBilled": true,
"isProratable": true,
"deductions": [],
"fees": [],
"invoice": {
"number": "2822835",
"date": "2020-11-16T00:00:00",
"periodFrom": "2020-10-09T00:00:00",
"periodTo": "2020-11-08T00:00:00"
},
"taxes": [
{
"name": "GST",
"appliedRate": 5.0
},
{
"name": "QST",
"appliedRate": 9.975
}
],
"tags": [
{
"name": "CustomerId",
"value": "42c8edf4-365a-4068-bde6-33675832afbb"
},
{
"name": "CustomerDisplayName",
"value": "Blue Sky Group"
},
{
"name": "CustomerPath",
"value": "Devmesh Co-Branded/Blue Sky Group"
}
]
}
]
}
Here the actual snippet of code I'm actually
let
...
Response2 = Table.FromRecords( { Response } ),
#"Expand1" = Table.ExpandListColumn(Response2, "charges"),
#"Expand2" = Table.ExpandRecordColumn(#"Expand1", "charges", {"productId", "productName", "sku", "chargeId", "chargeName", "chargeType", "periodFrom", "periodTo", "quantity", "listPrice", "netPrice", "netPriceProrated", "subTotal", "currency", "isBilled", "isProratable", "deductions", "fees", "invoice", "taxes", "tags"}, {"charges.productId", "charges.productName", "charges.sku", "charges.chargeId", "charges.chargeName", "charges.chargeType", "charges.periodFrom", "charges.periodTo", "charges.quantity", "charges.listPrice", "charges.netPrice", "charges.netPriceProrated", "charges.subTotal", "charges.currency", "charges.isBilled", "charges.isProratable", "charges.deductions", "charges.fees", "charges.invoice", "charges.taxes", "charges.tags"})
in
#"Expand2"

Json Array Query-Power BI

Hi i have the below JSON, would like to extract in PowerBI Query. My query is not able to extract Array's inside the JSON. I am unable to extract properties array values, where as i am able to extract user values.
Any help appreciated
Edit1: Added additional column Renames and achieved result based on
#AnkUser solution
Edit2: Below JSON
I would like form the power query to return as
Workers WorkCode Place
-----------------------
Manager 134 UK
delegate 135 Europe
Authority etc
There is no relationship between these columns. However, they will be used as additional filter data for the previous Query
Sample JSON
{
"Data": [
{
"Type": "Workers",
"Values": [
"Manager",
"Delegate",
"Authority"
]
},
{
"Type": "WorkCode",
"Values": [
"134",
"135",
"140",
"141",
"142",
"143",
"150"
]
},
{
"Type": "Place",
"Values": [
"UK",
"Europe"
]
}
]
}
Below Sample power query:
let
Source = Json.Document(Web.Contents("http:localhost")),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"User", "Properties"}, {"Column1.User", "Column1.Properties"}),
#"Expanded Column1.User" = Table.ExpandRecordColumn(#"Expanded Column1", "Column1.User", {"recId", "Description", "Type", }, {"Column1.User.recId", "Column1.User.Description", "Column1.User.Type"}),
#"Expanded Column1.Properties" = Table.ExpandListColumn(#"Expanded Column1.User", "Column1.Properties"),
#"Expanded Column1.Properties1" = Table.ExpandRecordColumn(#"Expanded Column1.Properties", "Column1.Properties", {"PersonID", "HomeRef", "Designation", "EstateAgent", "Mortgage", "Broker", "Citizen"}, {"Column1.Properties.PersonID", "Column1.Properties.HomeRef", "Column1.Funds.Designation", Column1.Properties.EstateAgent", Column1.Properties.Mortgage", Column1.Properties.Broker",Column1.Properties.Citizen"})
)
in
#"Expanded Column1"
Sample data:
[
{
"User": {
"recId": "0154911",
"Description": "Lindsay Properties ltd",
"Type": "Organisation",
"Properties": [
{
"PersonID": 5636,
"HomeRef": 149065,
"Designation":"Owner",
"EstateAgent": {
"Code": "8533",
"Description": "Hunters-properties"
},
"Mortgage": {
"Code": "natwide",
"Description": "Bank limited"
},
"Broker": {
"Description": "Managecentre"
},
"Citizen": {
"UK": true,
"USA": false,
"Europe": false
}
},
{
"PersonID": 5636,
"HomeRef": 149066,
"Designation":"Owner",
"EstateAgent": {
"Code": "8533",
"Description": "Hunters-properties"
},
"Mortgage": {
"Code": "natwide",
"Description": "Bank limited"
},
"Broker": {
"Description": "Managecentre"
},
"Citizen": {
"UK": false,
"USA": false,
"Europe": false
}
}
]
}
},
{
"User": {
"recId": "0154912",
"Description": "Mr Mortimier properties",
"Type": "Person",
"Properties": [
{
"PersonID": 1636,
"HomeRef": 199065,
"Designation":"Owner",
"EstateAgent": {
"Code": "9533",
"Description": "Whitegates-properties"
},
"Mortgage": {
"Code": "Yoskhire society",
"Description": "society limited"
},
"Broker": {
"Description": "Managecentre"
},
"Citizen": {
"UK": true,
"USA": true,
"Europe": false
}
},
{
"PersonID": 1636,
"HomeRef": 199066,
"Designation":"Authority",
"EstateAgent": {
"Code": "9533",
"Description": "Whitegates-properties"
},
"Mortgage": {
"Code": "Yoskhire society",
"Description": "society limited"
},
"Broker": {
"Description": "Managecentre"
},
"Citizen": {
"UK": true,
"USA": true,
"Europe": false
}
}
]
}
}]
If I understand your question correctly, You want your array from propeties to be expanded as column for a Row.
To Test your use case I have used your data and I tried to create rows from it. Below screenshot is the result.
If this is what you need, below is the query I got from PowerBI which gives result.
Note: You might want to clean Names of column.
let
Source = Json.Document(File.Contents("C:\Users\achikhale\Desktop\stackoverflowPowerBIJson.json")),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"User"}, {"Column1.User"}),
#"Expanded Column1.User" = Table.ExpandRecordColumn(#"Expanded Column1", "Column1.User", {"recId", "Description", "Type", "Properties"}, {"Column1.User.recId", "Column1.User.Description", "Column1.User.Type", "Column1.User.Properties"}),
#"Expanded Column1.User.Properties" = Table.ExpandListColumn(#"Expanded Column1.User", "Column1.User.Properties"),
#"Expanded Column1.User.Properties1" = Table.ExpandRecordColumn(#"Expanded Column1.User.Properties", "Column1.User.Properties", {"PersonID", "HomeRef", "Designation", "EstateAgent", "Mortgage", "Broker", "Citizen"}, {"Column1.User.Properties.PersonID", "Column1.User.Properties.HomeRef", "Column1.User.Properties.Designation", "Column1.User.Properties.EstateAgent", "Column1.User.Properties.Mortgage", "Column1.User.Properties.Broker", "Column1.User.Properties.Citizen"}),
#"Expanded Column1.User.Properties.EstateAgent" = Table.ExpandRecordColumn(#"Expanded Column1.User.Properties1", "Column1.User.Properties.EstateAgent", {"Code", "Description"}, {"Column1.User.Properties.EstateAgent.Code", "Column1.User.Properties.EstateAgent.Description"}),
#"Expanded Column1.User.Properties.Mortgage" = Table.ExpandRecordColumn(#"Expanded Column1.User.Properties.EstateAgent", "Column1.User.Properties.Mortgage", {"Code", "Description"}, {"Column1.User.Properties.Mortgage.Code", "Column1.User.Properties.Mortgage.Description"}),
#"Expanded Column1.User.Properties.Broker" = Table.ExpandRecordColumn(#"Expanded Column1.User.Properties.Mortgage", "Column1.User.Properties.Broker", {"Description"}, {"Column1.User.Properties.Broker.Description"}),
#"Expanded Column1.User.Properties.Citizen" = Table.ExpandRecordColumn(#"Expanded Column1.User.Properties.Broker", "Column1.User.Properties.Citizen", {"UK", "USA", "Europe"}, {"Column1.User.Properties.Citizen.UK", "Column1.User.Properties.Citizen.USA", "Column1.User.Properties.Citizen.Europe"})
in
#"Expanded Column1.User.Properties.Citizen"
If this is what you need I could add some more explanation (steps) on how I achieved this model of data
Edit:
New query for Data Note: your Json
let
Source = Json.Document(File.Contents("C:\Users\achikhale\Desktop\stackoverflowPowerBIJson1.json")),
#"Converted to Table" = Record.ToTable(Source),
#"Expanded Value" = Table.ExpandListColumn(#"Converted to Table", "Value"),
#"Expanded Value1" = Table.ExpandRecordColumn(#"Expanded Value", "Value", {"Type", "Values"}, {"Value.Type", "Value.Values"}),
#"Expanded Value.Values" = Table.ExpandListColumn(#"Expanded Value1", "Value.Values")
in
#"Expanded Value.Values"
But if I edit your Json as below
[{
"Data": [{
"Type": "Workers",
"Values": [
"Manager",
"Delegate",
"Authority"
]
}, {
"Type": "WorkCode",
"Values": [
"134",
"135",
"140",
"141",
"142",
"143",
"150"
]
}, {
"Type": "Place",
"Values": [
"UK",
"Europe"
]
}
]
}
]
Then you will get more clean Table and it's rows with below query.
Note below query will only work with my edited Json mentioned above.
let
Source = Json.Document(File.Contents("C:\Users\achikhale\Desktop\stackoverflowPowerBIJson1.json")),
#"Converted to Table" = Table.FromList(Source, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Data"}, {"Column1.Data"}),
#"Expanded Column1.Data" = Table.ExpandListColumn(#"Expanded Column1", "Column1.Data"),
#"Expanded Column1.Data1" = Table.ExpandRecordColumn(#"Expanded Column1.Data", "Column1.Data", {"Type", "Values"}, {"Column1.Data.Type", "Column1.Data.Values"}),
#"Expanded Column1.Data.Values" = Table.ExpandListColumn(#"Expanded Column1.Data1", "Column1.Data.Values")
in
#"Expanded Column1.Data.Values"

Flask restless - A search filter for a relationship.property != val in case of one-to-many relationship

Flask-sqlalchemy Models for my book and actions tables are
class Book(db.Model):
__tablename__ = 'book'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
activity = db.relationship('Actions')
class Actions(db.Model):
__tablename__ = 'actions'
id = db.Column(db.Integer, primary_key=True)
book_id = db.Column(db.Integer, db.ForeignKey('book.id'), nullable=False)
action = db.Column(db.Enum(['requested', 'issued', 'opened', 'closed']), nullable=True)
created_on = db.Column(db.DateTime, default=_get_date_time)
Basically it's a one-to-many relationship between a book and actions. And I am using flask-restless for the API.
I need to get
All books that have not been closed
I have tried below search queries
q={
"filters": [
{
"name": "activity",
"op": "any",
"val": {
"name": "action",
"op": "not_equal_to",
"val": "closed"
}
}
]
}
and
q={
"filters": [
{
"name": "activity",
"op": "any",
"val": {
"name": "action",
"op": "not_in",
"val": ["closed"]
}
}
]
}
But I am getting wrong result
{
"num_results": 30,
"objects": [
{
"activity": [
{
"action": "opened",
"created_on": "2015-06-05T17:05:07",
"id": 31
},
{
"action": "closed",
"created_on": "2015-06-05T17:05:44",
"id": 32
}
],
"id": 1,
"name": "K&R"
....
},
...
]
"page": 1,
"total_pages": 3
}
Am I making some mistake here or this kind of thing is not possible in restless?
Please help me out.
Try this:
q = { "filters":[
{
"name":"activity__action",
"op":"not_equal_to",
"val":"closed"
}
]
}