SubSonic3 SetExpression problem - subsonic3

Next SubSonic3 query gives me an error:
Db.Update<Tag>()
.SetExpression("Popularity")
.EqualTo("Popularity+1")
.Where<Tag>(x => x.TagId == tagId)
.Execute();
Error: failed: System.FormatException : Failed to convert parameter value from a String to a Int32.
The sql that is generated is ok, but the collection of parameters contains two parameters that need to be set.
UPDATE [Tagging].[Tag]
SET Popularity=Popularity+1
WHERE [Tagging].[Tag].[TagId] = #0
One of the parameters set #up_Popularity to 'Popularity+1'. Since this is the first parameter being set, sql triese to assign this string 'Popularity+1' to an integer.
Is this a bug or am I doing something wrong?

Db.Update<Tag>()
.SetExpression("Popularity = Popularity + 1")
.Where<Tag>(x => x.TagId == tagId)
.Execute();
This should work ... but I think it's for wholesale updates. Not sure. Your best bet is to use our CodingHorror:
new CodingHorror("UPDATE Tags SET Popularity = Popularity + 1 WHERE #1",
tagId).Execute();

I'd be amazed if that was supposed to work. When I need to have a string evaluated as part of the SQL (and not by SubSonic) I almost always end up having to use a CodingHorror.
However, you should be able to do this by using a separate query. Something like:
Db.Update<Tag>()
.Set("Popularity")
.EqualTo(Tag.SingleOrDefault(t => t.TagId == tagId).Popularity + 1)
.Where<Tag>(x => x.TagId == tagId)
.Execute();

Related

calculate range of values entered by user Custom function Google Appscript

I want to use arrayformula for my custom function if possible because I want to input a range of values
I also get this error: TypeError: Cannot read property "0" from null.
Also, this: Service invoked too many times in a short time: exec qps. Try Utilities.sleep(1000) between calls
var regExp = new RegExp("Item: ([^:]+)(?=\n)");
var matches=new regExp(input);
return matches[0];
}
Really appreciated some help
Edit:
Based on the second picture, I also try using this regex formula to find word start with "Billing address"
But for the first picture, I used regex formula to find word start with "Item"
The error appears the same for both custom function.
If you want to use a custom function which finds all the strings that start with Item or item and extracts the contents from after the finding, you can use the code provided below. The regular expression is checked by using the match() function and returns the desired result; otherwise, it will return null.
function ITEM(input) {
var regEx = /(?:I|i)tem\s*(.*)$/;
var matches = input.match(regEx);
if (matches && matches.length > 1) {
return matches[1];
} else {
return null;
}
}
If you want to use the RegExp like you did in the code you have shared, you should use \\ instead of \.
For checking and verifying the regular expressions you can use this site.
The Service invoked too many times in a short time: exec qps. Try Utilities.sleep(1000) between calls. error message you are getting is due to the fact that you are trying to call the custom function on too many cells - for example dragging the custom function on too many cells at once. You can check more about this error message here.

IF Formula returning error or not doing a section of the formula

I have a formula in my report to select a field based on requirements:
if not isnull({EXT_TBL.EXT_KEY_TYPE}) then
(if {EXT_TBL.EXT_KEY_TYPE} = "SO" and {EXT_TBL.EXT_ACTION_FLAG_9} = "Y"
then {EXT_TBL.EXT_TEXT})
else '0'
When I run the report it works ok until I try to load a specific page. When I try to load the page I get an error of 'The string is non numeric'. The formula is called in another formula:
{COR_TBL.COR_EXPECTED_DATE} + 2 + ToNumber({#FRM_NOTES})
I have ran the query on the server of:
SELECT * FROM EXT_TBL WHERE EXT_KEY_TYPE = "SO" AND EXT_ACTION_FLAG_9 = "Y";
This returned me two rows of data. I have narrowed it down to a specific entry that is causing the issue, but in the database the row has N in the field action flag 9 instead of Y so it shouldn't be throwing me the error in my report.
The action field 9 is flagged on only two records both of which contain a 7 in the EXT_TEXT feild so I have no idea why I am getting the error.
I also tried a nested if statement of:
if not isnull({EXT_TBL.EXT_KEY_TYPE}) then
(if {EXT_TBL.EXT_KEY_TYPE} = "SO" then (if {EXT_TBL.EXT_ACTION_FLAG_9} = "Y"
then {EXT_TBL.EXT_TEXT}))
else '0'
But it still gave me the same error.
Thanks
I was able to fix the issue by removing the nested if statement and just putting all the conditions in the original statement:
if not isnull({EXT_TBL.EXT_KEY_TYPE}) AND {EXT_TBL.EXT_KEY_TYPE} = "SO"
AND {EXT_TBL.EXT_ACTION_FLAG_9} = "Y"
THEN {EXT_TBL.EXT_TXT} ELSE '0'
This seems to have fixed the issue.

How to ensure that user can input any datatype (str, float, int, boolean...)?

So this is my first question on the forum and I hope I am doing it correct.
General question: How can I ensure that python does not return any errors when writing a script that allows the user to input values of different datatypes depending on the context or parameter they want to change?
More specific: I am new to python and want to write a script that allows users of The Foundry's Nuke to change values on multiple nodes of the same class at once. Depending on whether the desired parameter to change is a checkbox('bool'), and RGBA input ('4 floats')... the input has to be of a different type. Searching the forum I found that the type can be checked by type() function and compared in an if statement with the isinstance() function. I guess I could work with that, but the type of e.g. a Gradenode's multiply knob returns type 'AColor_Knob'. I expected something like float. And comparing it in an isinstance() does not give me a match regardless of the datatype I am comparing to.
Mainscript so far:
nukescripts.clear_selection_recursive()
userInput = nuke.getInput('Which type of nodes would you like to select? (!!!first char has to be capitalized!!!)',
'Shuffle')
matchingNodes = []
for each in nuke.allNodes():
if each.Class() == userInput:
matchingNodes.append(each)
else:
pass
for i in matchingNodes:
i.setSelected(True)
nuke.message(str(len(
matchingNodes)) + ' matching Nodes have been found and are now selected! (if 0 there either is no node of this type or misspelling caused an error!)')
userInput_2 = nuke.getInput('Which parameter of these nodes would you like to change? \n' +
'(!!!correct spelling can be found out by hovering over parameter in Properties Pane!!!)',
'postage_stamp')
userInput_3 = nuke.getInput('To what do you want to change the specified parameter? \n' +
'(allowed input depends on parameter type (e.g. string, int, boolean(True/False)))', 'True')
for item in matchingNodes:
item.knob(userInput_2).setValue(userInput_3)
How I checked the datatypes so far:
selected = nuke.selectedNode()
knobsel = selected.knob('multiply')
print(type(knobsel))
#if type(knobsel) == bool:
if isinstance(knobsel, (str,bool,int,float,list)):
print('match')
else:
print('no match')
You can call a TCL command with nuke.tcl(). In TCL, everything is a string, so type is irrelevant (in some commands).
p = nuke.Panel('Property Changer')
p.addSingleLineInput('class', '')
p.addSingleLineInput('knob', '')
p.addSingleLineInput('value', '')
p.show()
node_class = p.value('class')
knob_name = p.value('knob')
knob_value = p.value('value')
for node in nuke.allNodes(node_class):
tcl_exp = 'knob root.{0}.{1} "{2}"'.format(node.fullName(),knob_name,knob_value)
print tcl_exp
nuke.tcl(tcl_exp)
That should answer your question. There are many ways to approach what you're trying to do - if you want to keep it all in python, you can do type checking on the value of the knob. For example:
b = nuke.nodes.Blur()
print type(b.knob('size').value()).__name__
This creates a Blur node and prints the string value of the type. Although I don't recommend this route, you can use that to convert the value:
example = '1.5'
print type(example)
exec('new = {}(example)'.format('float'))
print type(new)
An alternative route to go down might be building yourself a custom lookup table for knob types and expected values.
Edit:
TCL Nuke Commands:
http://www.nukepedia.com/reference/Tcl/group__tcl__builtin.html#gaa15297a217f60952810c34b494bdf83d
If you press X in the nuke Node Graph or go to File > Comp Script Command, you can select TCL and run:
knob root.node_name.knob_name knob_value
Example:
knob root.Grade1.white "0 3.5 2.1 1"
This will set values for the named knob.

TypeError during executemany() INSERT statement using a list of strings

I am trying to just do a basic INSERT operation to a PostgreSQL database through Python via the Psycopg2 module. I have read a great many of the questions already posted regarding this subject as well as the documentation but I seem to have done something uniquely wrong and none of the fixes seem to work for my code.
#API CALL + JSON decoding here
x = 0
for item in ulist:
idValue = list['members'][x]['name']
activeUsers.append(str(idValue))
x += 1
dbShell.executemany("""INSERT INTO slickusers (username) VALUES (%s)""", activeUsers
)
The loop creates a list of strings that looks like this when printed:
['b2ong', 'dune', 'drble', 'drars', 'feman', 'got', 'urbo']
I am just trying to have the code INSERT these strings as 1 row each into the table.
The error specified when running is:
TypeError: not all arguments converted during string formatting
I tried changing the INSERT to:
dbShell.executemany("INSERT INTO slackusers (username) VALUES (%s)", (activeUsers,) )
But that seems like it's merely treating the entire list as a single string as it yields:
psycopg2.DataError: value too long for type character varying(30)
What am I missing?
First in the code you pasted:
x = 0
for item in ulist:
idValue = list['members'][x]['name']
activeUsers.append(str(idValue))
x += 1
Is not the right way to accomplish what you are trying to do.
first list is a reserved word in python and you shouldn't use it as a variable name. I am assuming you meant ulist.
if you really need access to the index of an item in python you can use enumerate:
for x, item in enumerate(ulist):
but, the best way to do what you are trying to do is something like
for item in ulist: # or list['members'] Your example is kinda broken here
activeUsers.append(str(item['name']))
Your first try was:
['b2ong', 'dune', 'drble', 'drars', 'feman', 'got', 'urbo']
Your second attempt was:
(['b2ong', 'dune', 'drble', 'drars', 'feman', 'got', 'urbo'], )
What I think you want is:
[['b2ong'], ['dune'], ['drble'], ['drars'], ['feman'], ['got'], ['urbo']]
You could get this many ways:
dbShell.executemany("INSERT INTO slackusers (username) VALUES (%s)", [ [a] for a in activeUsers] )
or event better:
for item in ulist: # or list['members'] Your example is kinda broken here
activeUsers.append([str(item['name'])])
dbShell.executemany("""INSERT INTO slickusers (username) VALUES (%s)""", activeUsers)

How to query multi values of enum field in ActiveRecord?

mymodel.rb
enum status: { posted: 1, failed: 2, suspended: 3 }
mycontroller.rb
def filter_params
params.fetch(:mymodel, {}).
permit(
:status => []
)
end
And i have params like mymodel[:status] => ["failed", "suspended"]
How can i get all results by status is failed and suspended
Something like: Mymodel.where(status: filter_params[:status])
Thanks a lot!
And when a call:
#mymodel = Mymodel.new(filter_params)
I got this error:
'["failed", "suspended"]' is not a valid status
When running a query, you need to supply the ordinal values for the enum attribute. So instead of strings like 'failed' or 'suspended', you need to query using their integer values.
Luckily, you can access a hash to easily map all the statuses to integers from your filter_params hash:
values = Mymodel.statuses.values_at(*Array(filter_params[:status]))
With that you can run your query to get all records which have any of the filtered statuses:
Mymodel.where(status: values)
You don't want to scatter that piece of code all over the place though, so I recommend you'd implement this as a scope in your model:
class Mymodel < ActiveRecord::Base
enum status: { posted: 1, failed: 2, suspended: 3 }
scope :for_statuses, ->(values) do
return all if values.blank?
where(status: statuses.values_at(*Array(values)))
end
end
Note that the return all if values.blank? line makes it possible to throw in nil or an empty array without breaking your query.
You can now easily query the records:
Mymodel.for_statuses(filter_params[:status])
Note that you cannot create a record which has multiple statuses. enum only restricts the values that can be assigned, but you can assign only one, otherwise you get the not a valid status error.
See the Rails documentation for more information about enum.
In Rails 5 you can now pass a string array to the query, e.g:
Mymodel.where(status: ['failed', 'suspended'])
For earlier versions, just convert your array values to symbols:
statuses = filter_params[:status].map(&:to_sym)
Mymodel.where(status: statuses)