how to use F expression to first cast a string to int, then add 1 to it then cast to string and update - django-queryset

I have a DB column which is generic type for some stats(qualitative and quantitative info).
Some values are string - type A and some values are numbers stored as string - type B.
What i want to do is cast the B types to number then add one to them and cast back to string and store.
Metadata.objects.filter(key='EVENT', type='COUNT').update(value=CAST(F(CAST('value', IntegerField()) + 1), CharField())
What i want to do is avoid race conditions using F expression and
update in DB.
https://docs.djangoproject.com/en/4.0/ref/models/expressions/#avoiding-race-conditions-using-f
It says in below post that casting and updating in db is possible for mysql
Mysql Type Casting in Update Query
I also know we can do arithmetic very easily on F expressions as it supports it and we can override functionality of add as well. How to do arthmetic on Django 'F' types?
How can i achieve Cast -> update -> cast -> store in Django queryset?

Try using annotation as follows:
Metadata.objects
.filter(key='EVENT', type='COUNT')
.annotate(int_value=CAST('value', IntegerField()))
.update(value=CAST(F('int_value') + 1, CharField())
Or maybe switching F and CAST works?
Metadata.objects
.filter(key='EVENT', type='COUNT')
.update(value=CAST( # cast the whole expression below
CAST( # cast a value
F('value'), # of field "value"
IntegerField() # to integer
) + 1, # then add 1
CharField() # to char.
)
I've added indentation, it helps sometimes to find the errors.
Also, doc says, CAST accepts field name, not an F-object. Maybe it works without F-object at all?
UPD: switched back to first example, it actually works :)

I believe the answer from #som-1 was informative but not substantiated with info or debugged data. I believe assuming is not always right.
I debugged the mysql queries formed in these two cases -
1 - Metadata.objects.update(value=Cast(Cast(F('value'), output_field=IntegerField()) + 1, output_field=CharField()))
2 - Metadata.objects.update(value=Cast(Cast('value', IntegerField()) + 1, CharField())) and
both give the same output as expected.
UPDATE Metadata SET value = CAST((CAST(value AS signed integer) + 1) AS char) WHERE ( key = 'EVENT' AND type = 'COUNT' )
Please find the link to add mysqld options to my.cnf and debug your queries. Location of my.cnf file on macOS
enabling queries - https://tableplus.com/blog/2018/10/how-to-show-queries-log-in-mysql.html

Related

How to call Lua table value explicitly when using integer counter (i,j,k) in a for loop to make the table name/address?

I have to be honest that I don't quite understand Lua that well yet. I am trying to overwrite a local numeric value assigned to a set table address (is this the right term?).
The addresses are of the type:
project.models.stor1.inputs.T_in.default, project.models.stor2.inputs.T_in.default and so on with the stor number increasing.
I would like to do this in a for loop but cannot find the right expression to make the entire string be accepted by Lua as a table address (again, I hope this is the right term).
So far, I tried the following to concatenate the strings but without success in calling and then overwriting the value:
for k = 1,10,1 do
project.models.["stor"..k].inputs.T_in.default = 25
end
for k = 1,10,1 do
"project.models.stor"..j..".T_in.default" = 25
end
EDIT:
I think I found the solution as per https://www.lua.org/pil/2.5.html:
A common mistake for beginners is to confuse a.x with a[x]. The first form represents a["x"], that is, a table indexed by the string "x". The second form is a table indexed by the value of the variable x. See the difference:
for k = 1,10,1 do
project["models"]["stor"..k]["inputs"]["T_in"]["default"] = 25
end
You were almost close.
Lua supports this representation by providing a.name as syntactic sugar for a["name"].
Read more: https://www.lua.org/pil/2.5.html
You can use only one syntax in time.
Either tbl.key or tbl["key"].
The limitation of . is that you can only use constant strings in it (which are also valid variable names).
In square brackets [] you can evaluate runtime expressions.
Correct way to do it:
project.models["stor"..k].inputs.T_in.default = 25
The . in models.["stor"..k] is unnecessary and causes an error. The correct syntax is just models["stor"..k].

The function "REVERSE" does not support the data type "DT_I4" for parameter number 1

i'm trying to make an expression for one of my variables in visual studio and I get this error saying:
The function "REVERSE" does not support the data type "DT_I4" for
parameter number 1. The type of the parameter could not be implicitly
cast into a compatible type for the function. To perform this
operation, the operand needs to be explicitly cast with a cast
operator.
Evaluating function "REVERSE" failed with error code 0xC0047089.
And this is my code:
SUBSTRING(#[User::FileName] , 1, REVERSE(FINDSTRING(#[User::FileName],"_", 1)))
Please help
Error message is pretty clear, you are doing a REVERSE of a FINDSTRING.
REVERSE's parameter needs to be literal values and FINDSTRING returns an integer (DT_I4).
I believe you want to do it the other way arround, first REVERSE the string and then calculate the position of the underscore, so that the SUBSTRING can take characters up to that point:
SUBSTRING(#[User::FileName] , 1, FINDSTRING(REVERSE(#[User::FileName]),"_", 1))
Edit: Try this to retrieve the last part after the last _.
SUBSTRING(
#[User::FileName],
LEN(#[User::FileName]) - FINDSTRING(REVERSE(#[User::FileName]),"_", 1) + 2,
LEN(#[User::FileName])
- (LEN(#[User::FileName]) - FINDSTRING(REVERSE(#[User::FileName]),"_", 1) + 2)
- FINDSTRING(REVERSE(#[User::FileName]),".", 1) + 1)

Mismtach Error in Foxpro SQL insertion

I need someone could help me out on how to trace the error of "mismatched data type" in visual foxpro 6.0 When I issues a command like this "insert into tmpcur from memvar".
tmpcur is a cursor having bulk numbers of columns and it is ready hard to trace which one is having mismatch in data type for insertion problem.
It is pretty difficult to trace the insertion loop of each record into VFP tables one by one unliked MSSQL profiler.
Appreciate to someone could help. Thanks.
This should help you. I have a temp cursor created with some bogus field / column names testing for types of character, integer, double, currency, date and time. Trying to follow what is the result of your scenario, I am taking the memory variable of "bbbb" which should be double (or numeric at the least), and changed it to a string.
I am then HOLDING the error trapping routine that MAY be in effect, then setting my own (as I don't think try/catch existed in VFP6.. it may, but I just don't remember. So, I did an ON ERROR, set a variable to true. Then, I default it to false, try the insert, then check the flag. If the flag IS set, then I go into a loop and try for each column in the given table/alias (in my example it is "C_Tmp", so replace with your table/alias). It goes through each variable, and if the data type is different from the table structure, it will dump the column name and table / memory value for you to review.
You could put this to a log file or something.
Now, another consideration. Some types are completely valid and common for implied conversion, such as character and memo fields can both get strings. Integer, double, float, currency can all work with generic "numeric" values.
So, if you encounter these differences, then we can go one level further and look for comparable types, but let me know and we can adjust as needed.
At least this should give you a huge jump to your insert issue.
CREATE CURSOR C_tmp ( cccc c(10), iiii i, bbbb b(2), ccyyyy y, ddd d, tttt t )
SCATTER MEMVAR memo
m.bbbb = "wrong data type, was double with 2 decimal"
lcHoldError = ON("ERROR")
ON ERROR lFailInsert = .t.
lFailInsert = .f.
INSERT INTO C_Tmp FROM memvar
IF lFailInsert
FOR lnI = 1 TO FCOUNT( "C_Tmp" )
lcTmp = FIELD( lnI, "C_Tmp" )
IF NOT TYPE( "C_Tmp." + lcTmp ) == TYPE( "m.&lcTmp" )
? "Invalid " + lcTmp + ", C_Tmp.&lcTmp, m.&lcTmp
ENDIF
ENDFOR
ENDIF
ON ERROR &lcHoldError

Ruby: how to insert Hash value into Cassandra map

Am attempting to store values provided as int, time, hash into Cassandra using Datastax driver.
Hash appears as { "Q17.1_4"=>"val", "Q17.2"=>"other", ...}
Have defined table as:
int
timestamp
map
PK( int, timestamp )
I can get the PK inserted ok but am having trouble coercing the hash values into something that Cassandra can cope with.
Have created a prepared statement and using it while (trying to) looping through values:
stmt = session.prepare( "insert into forms( id, stamp, questions ) values ( ?,?,? )" )
...
json_val.each{ |key,val|
result = session.execute( stmt, val[ 'ID' ].to_i, Time.parse( val[ 'tDate' ]).to_i, val )
}
If I insert 'val' as a hash I get this error:
/lib/cassandra/statements/prepared.rb:53:in `bind': expecting exactly 3 bind parameters, 2 given (ArgumentError)
This says (to me) that there isn't a method to convert the hash to what Cassandra wants.
If I insert the val as a string (using hash.to_s) I get this error:
/lib/cassandra/protocol/type_converter.rb:331:in varchar_to_bytes': undefined methodencode' for 1:Fixnum (NoMethodError)
... same goes for converting it to a json string, changing double quotes to single and so on.
I can insert the values using the cqlsh (command line) ( EG insert into forms (id, stamp, questions) values ( 123, 12345678, { 'one':'two','three':'four'});)
So the question is - how do I get this Ruby hash into a format that the Cassandra driver will accept?
Using:
Ruby 2.1.3
Cassandra 2.0 (with latest Datastax driver)
EDIT:
JSON value of 'questions' hash is { "Q17.1_4":"val", "Q17.2":"other", ...}
Also - I can insert the first two columns just fine. Omitting the third value from the insert statement works so I know those two values aren't the culprit here.
Found two problems:
There is a note in the docs:
Last argument will be treated as options if it is a Hash. Therefore, make sure to pass empty options when executing a statement with the last parameter required to be a map datatype.
When I either put an empty hash as the last parameter or swapped my hash value for a different param the error message changed to:
type_converter.rb:331:in varchar_to_bytes': undefined methodencode' for 1:Fixnum (NoMethodError)
This lead me to believe that there was an invalid value in there somewhere. To fix this I created a temp hash and checked every value to make sure it was a string before adding it to this temp hash. Then using this temp value I was able to add to the DB using the stored procedure.

Overlay char string with a pattern

I wanna add the missing spaces in a character variable.
For instance bu_partner is char10 and has the value 31. In a standard database table there is only the value 0000000031.
I tried the overlay command, but 31 is at the beginning and not at the end.
DATA: mask TYPE bu_partner VALUE '0000000000',
partner TYPE bu_partner.
partner = '31'.
OVERLAY partner WITH mask.
write partner.
Output:
3100000000
Is there any way to achieve 0000000031?
Use the appropriate conversion exit as designated by the domain:
DATA: some_value TYPE c LENGTH 10,
partner TYPE bu_partner.
some_value = '31'.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = some_value
IMPORTING
output = partner.
WRITE: / partner USING NO EDIT MASK.
Be aware that you need to WRITE ... USING NO EDIT MASK in this case - if you don't use this addition, the list processing will automatically invoke CONVERSION_EXIT_ALPHA_OUTPUT which will eliminate the leading zeroes.
Please check the conversion routine mapped to the domain of bu_partner. You can check that in the domain which is mapped to the data element of bu_partner. I am guessing it would be ALPHA. Which means you should use the FM CONVERSION_EXIT_ALPHA_INPUT to convert external data to internal format ( if you input 31 then you would get output as 0000000031 ) . If you want to convert internal to external then use the FM CONVERSION_EXIT_ALPHA_OUTPUT where appropriate.
After some digging, I found the command UNPACK.
DATA: lv_partner_leading_zeros(10) type c,
lv_partner TYPE bu_partner.
lv_partner = '31'.
UNPACK lv_partner to lv_partner_leading_zeros.

Resources