How to generate FilterExpression without hard-coding the attribute names? - python-3.x

I know one can scan or query like this:
response = table.scan(
FilterExpression=Attr('first_name').begins_with('J') &
Attr('account_type').eq('super_user') )
How do I do this without hard coding the attribute names?
To clarify, given such dictionary, I wish to table scan as such;
attr_dict = {"foo":42, "bar":52}
response = table.scan(
FilterExpression=Attr('foo').eq(42) &
Attr('bar').eq(52) )
If it's a sql, although one wouldn't do it, they can do
"select * from table where {} = {} and {} = {}".format(a,b,x,y).
The problem I'm having is how would I & the two using a loop of some sort.

Just create the FilterExpression by looping over the entries in the dictionary. You can use boolean logic to combine individual expressions as follows (just build the filter expression string manually):
foo = 42 AND bar = 52

Related

Is there a way use a loop to reiterate a table in power query?

I need a way to reiterate a table N amount of times. I have 1 main table (MainTable) which needs to be processed by each item in a List (ListofItems). It is processed in a function (Funct1) where it takes in 1 item in the ListofItems and transforms the MainTable into a new table (NewTable). But I want to iterate the NewTable through Funct1 again for the next item in the ListofItems.
For Example, the flow would be like this:
total N items in ListofItems,
MainTable ->Funct1(Item1) -> NewTable1
NewTable1 ->Funct1(Item2) -> NewTable2
...
NewTableN ->Funct1(ItemN) -> FinalTable
I have tried using List.Generate but I don't think this can produce a table, so far I could only manage lists.
The furthest I have gotten is with List.Accumulate, it is able to pass each list of items into the function. But I don't know how to make it pass the NewTable back into itself.
let
MainTable = #"MainTable",
Source2 = #"TableofList",
TotalRow = Table.RowCount(Source2),
ListofItem = Source2[Column1],
output =
List.Accumulate(
{0..TotalRow},
[Item=0,NewTable=MainTable],
(result, count) =>
(NewTable as table)=>
let
Item=ListofItem{count},
NewTable = Funct1(Item,NewTable)
in
NewTable
)
in
output
Please help, I feel like I'm so close to getting it right but I'm lost on what else I can do.
I have managed to solve my problem. I was already really close, I should have used NewTable as the result, and the MainTable as the seed. I'll leave it here in case anyone else needs something similar.
let
MainTable = #"MainTable",
Source2 = #"TableofList",
TotalRow = Table.RowCount(Source2),
ListofItem = Source2[Column1],
output =
List.Accumulate(
{0..(TotalRow-1)},
MainTable,
(NewTable, count) =>
let
Item=ListofItem{count},
NewTable = Funct1(Item,NewTable)
in
NewTable
)
in
output
For further information, Funct1 is actually a function to inner join a column on the main table to a definition table. As I have a few columns to join, I wanted a loop function. I wanted it to be dynamic as the columns to join change from project to project. But the structure is all the same. Each Item in the ListofItem would be the name of the column to join to a separate definition table of the same name.
I'm not sure if my approach is a good way to do it, but it's the way I could think of. I'm open to suggestions if there is a better way to do this.

How do I autopopulate a tkinter table using a loop

I'm trying to auto-populate a tkinter table with the names of folders in a directory and details about their properties
grpdata_name = listdir(r"PATH")
grpdata_path = r"PATH\{}".format(grpdata_name[0])
grpdata_groupcount = -1
for x in grpdata_name :
grpdata_groupcount = grpdata_groupcount +1
grpdata_groupcurrent = 'grpdata_name{}{}{}'.format('[',grpdata_groupcount,']')
GUI_Table.insert(parent='',index='end',iid=0,text='',
values=('ID',grpdata_groupcurrent,'TIME CREATED','TIME MODIFIED','DEVICES'))
My current method is to change the selected element in a string. This creates a working cycle through each part of the string ( grpdata_name[0] , grpdata_name[1] etc)
I can't figure out how to use the contents of grpdata_groupcurrent as a variable, rather than a string.
This method isn't very efficient overall, so please let me know if there is a better way to do this.

M (PowerQuery), set the value of a non-primitive variable in a let statement

I'm writing a custom M Language (PowerQuery in Excel) function to query a RESTful interface. This interface has a large number of optional parameters.
Starting with a simple case- I handle an optional limit passed as a simple (primitive) value as follows-
/*
* RESTful API Get from the named endpoint
*/
(endpoint as text, optional limit) =>
let
// query limit
// If limit is supplied as a number, it will be converted to text
// If limit is not supplied it will be set to the value "1000"
limit = if limit <> null then Text.From(limit) else "1000",
As the full API has many paramaters I wanted to use a Record to pass them to the function, but then I realised I don't know how to persuade M to write the default values into the parameter record.
I tried a couple of options.
Direct access-
(endpoint as text, optional params as record) =>
let
params[limit] = if (params[limit] = null) then "1000",
the result is a syntax error-'Token equal expected'
Merging the new value of limit as a Record with "&"
(endpoint as text, optional params as record) =>
let
params = params & if params[limit] = null then [limit = "1000"] else [],
result syntax error-'Token Literal expected'
I'm clearly missing something about the syntax rules for let statements, I know I need a variable = value assignment, and it looks as if putting anything other than a plain variable name on the LHS to write elements inside a structured value is not allowed, but i'm not sure how to acieve this otherwise?
Not sure exactly what you want here, but to create a List of Records where some Records have a default parameter and others do not, you could try something like:
(newParams as record) =>
let
default = [limit=1000, param2=2, param3=3],
final = Record.Combine({default, newParams})
in
final
With regard to Record.Combine, the beauty is that the right hand record will override the left hand record if both are present; and it will just add to it if nothing is present.
So something like:
let
Source = [limit=400, param3="x", param7=246],
conv = fnParams(Source)
in
conv
=>
Depending on the required format of your output string, you can build it using List.Accumulate. eg:
let
Source = [limit=400, param3="x", param7=246],
conv = fnParams(Source),
list = List.Accumulate(List.Zip({Record.FieldNames(conv), Record.ToList(conv)}), "",
(state,current) =>state & "&" & current{0} & "=" & Text.From(current{1}) )
in
list
=> &limit=400&param2=2&param3=x&param7=246

Use value from a column as paramater for json request and combine the table

I am using power query to load some json data in a table (matches). I want to use a specific part of that data (fixture_id) as a parameter for another json request in another query (predictions), and then combine that output in my main (matches) table. Anyone can point me in the right direction on how to do this ?
So here is my matches table:
And then in my fixtures table i can maybe i have:
apiKey = Excel.CurrentWorkbook(){[Name="ApiKey"]}[Content]{0}[Column1],
fixtureID = "?",
Source = Json.Document(Web.Contents("https://v2.api-football.com/predictions/" & fixtureID, [Headers=[#"X-RapidAPI-Key"=apiKey]])),
If i hardcode the fixtureID, i get this output:
But i want to calculate it dynamically, and then merge the output to the matches table.
The first step is to turn your request into a function that accepts parameters. Put your request on a new blank query:
let
fnGetData = (fixtureID as text) =>
let
apiKey = Excel.CurrentWorkbook(){[Name="ApiKey"]}[Content]{0}[Column1],
fixtureID = "?",
Source = Json.Document(Web.Contents("https://v2.api-football.com/predictions/"
& fixtureID, [Headers=[#"X-RapidAPI-Key"=apiKey]]))
in
Source
in
fnGetData
Rename it to fnGetData.
Then, go to your table and click on Add Column/Add Custom Function. Select fnGetData and the input parameter is your fixtureID column. This should make all the requests and you'll just have to expand the new column results.

linq to entity Contains() and nested queries

i've a trouble with linq, i'll explain on example :
i have a database table called Employee which got FirstName and LastName columns,
and a method to search employees which gets a nameList list as argument, the elements in this list are names formatted like this one "Fred Burn", or this1 "Grim Reaper",
already tryed these approaches with no luck =[
//just all employees
var allData = from emp in Context.Employee select emp;
var test1 = from emp in allData
where(emp.FirstName + " " + emp.LastName).Contains
("" + ((from n in nameList select n).FirstOrDefault()))
select emp;
var test2 = (from emp in allData
where (emp.FirstName + " " + emp.LastName)
== ((from n in nameList select n).FirstOrDefault())
select emp);
var test3 = from emp in allData
where (from n in nameList select n).Contains
(emp.FirstName + " " + emp.LastName)
select emp;
first and second queries give : {"Unable to create a constant value of type 'Closure type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context."} exceptionand third : {"LINQ to Entities does not recognize the method 'Boolean Contains[String](System.Collections.Generic.IEnumerable`1[System.String], System.String)' method, and this method cannot be translated into a store expression."}
would be glad to hear your suggestions :)
Thank You!
p.s.
yea i know it's possible to split names in list and compare them separately, but still curious why wont these queries work.
I assume nameList in this case is an in memory collection and that you are trying to use the LINQ to SQL trick creating a SQL "IN" clause inside of the Entity Framework. Unfortunately, EF doesn't support this syntax (yet). Depending on the number of records you are trying to match, you may be able to run separate queries for each child you are desiring. Alternatively, you could build an entitysql query using concatenation to append the multiple items from the nameList as separate OR clauses in the WHERE operation.

Resources