Django BooleanField accepted values - mysql

I have a MySQL database where data are migrated from an Access database.
The problem is that access saves boolean true value as -1, while django saves boolean true value as 1 (as tipically happens with MySQL).
So, for boolean fields, old true values are saved as -1, while new true values are saved as 1.
I need to say to django to consider True both 1 and -1 for all boolean fields.
How can I do?
Thanks in advance,
Sabrina

Just update all of the old values to 1:
UPDATE <table>
SET <fieldname>=1
WHERE <fieldname>=-1

I don't have a clue what Django is, but if you did all your Boolean tests with NOT FALSE (or <>0) instead of with TRUE, it will work regardless of the actual value encoded for TRUE (-1 or 1).

Create a custom BooleanField class that extens from models.BooleanField. In the next class, true values are saved with -1 on DB.
class AccessCompatibleBooleanField(models.BooleanField):
def to_python(self, value):
if value == True:
return -1
if value == False:
return False
if value in ('t', 'True', '1', '-1'):
return -1
if value in ('f', 'False', '0'):
return False
raise exceptions.ValidationError(self.error_messages['invalid'])
If you want make filters like .filter(visibles=True) and visibles is custom boolean field, you have to add following method to your custom class.
def get_prep_value(self, value):
if value is None:
return None
b = bool(value)
if b:
return -1
return b

Related

Automatically cast JSON coded data in ruby

My challenge is that in the database, JSON code was untidily stored.
{'isr_comment':'Test Comment',
'isr_depression_1': '1',
'isr_depression_2': '1'
'isr_depression_3': '1'
'isr_tested': 'true'
}
You see, all values are defined as string but some should be integers. It would be the best to have clean data already in the database but I cannot control how the data is entered. However my model looks like this.
class SessionPart < ApplicationRecord
...
serialize :answers, JSON
...
end
As expected after deserialization is done I get strings as well.
#data=
{"isr_Comment"=>"Test Comment",
"isr_depression_1"=>"1",
"isr_depression_2"=>"1",
"isr_depression_3"=>"1",
"isr_tested" => "true"}
But I need to do some calculation with this data so I need all possible values with a meaningful type.
#data=
{"isr_Comment"=>"Test Comment",
"isr_depression_1"=>1,
"isr_depression_2"=>1,
"isr_depression_3"=>1,
"isr_tested" => true}
Is there any way to cast such data automatically?
You can pass your custom serializer to serialize function. That custom serializer would use JSON as source serializer and update the values as per your requirements.
class SessionPart < ApplicationRecord
...
serialize :answers, CustomSerializer #CustomSerializer must write 2 class level function named dump & load for serializing and de-serializing respectively
...
end
class CustomSerializer
def self.load(value)
normalize_hash(JSON.load(value))
end
def self.dump(value)
JSON.dump(value)
end
private
def self.normalize_hash hash
return hash unless hash.is_a? Hash
hash.transform_values {|v| normalize(v)}
end
#change this function as per your requirement, Currently it's handling boolean,integer,float & null rule set
def self.normalize(value)
case (value)
when 'true'
true
when 'false'
false
when 'null','nil'
nil
when /\A-?\d+\z/
value.to_i
when /\A-?\d+\.\d+\z/
value.to_f
else
value.is_a?(Hash) ? normalize_hash(value) : value
end
end
end
The suggested CustomSerializer seems to do its job very well, thanks. I did some small adjustments to be able to nest hashes.
class CustomSerializer
def self.load(value)
normalize_hash(JSON.load(value))
end
def self.dump(value)
JSON.dump(value)
end
private
def self.normalize_hash hash
return hash unless hash.is_a? Hash
hash.transform_values {|v| normalize(v) }
end
#change this function as per your requirement, Currently it's handling boolean,integer,float & null rule set
def self.normalize(value)
case (value)
when 'true'
true
when 'false'
false
when 'null','nil'
nil
when /\A-?\d+\z/
value.to_i
when /\A-?\d+\.\d+\z/
value.to_f
else
value.is_a?(Hash) ? normalize_hash(value) : value
end
end
end

MYSQL 5.7 UPDATE value with ternary (perform a true/false toggle)

I'm trying to toggle a table column between true and false. My most recent attempt--
UPDATE favorites SET favorited = (IF(favorited=true, 'false', 'true')) WHERE title="${recipe}"
--is giving me the following error:
ER_TRUNCATED_WRONG_VALUE: Truncated incorrect DOUBLE value: 'true'
Can any MYSQL geniuses guide me towards the correct syntax?
You are returning strings from the IF i.e. 'false', 'true' return booleans instead
UPDATE favorites
SET favorited = (IF(favorited=true, false, true)) .....
Small Note Genius not required in this case :)
If the data type of the column favorited is BOOLEAN then what you are doing is the negation of the current value so all you need is the operator NOT:
UPDATE favorites
SET favorited = not favorited
WHERE title="${recipe}"

How can I assign an output to a function call in python?

I know I can't necessarily assign values to function call, so how would I assign an output to that function call? I've built a function that checks if a location (row,col) is valid in puzzle(list). I built another function that returns the value at that location. I am now building a third function that calls those two functions to set a value at a specific location, if that value was initially none. If the value was able to be set, it needs to return True. If the value was not None, it doesn't need to be set and it should return false.
For example:
set_location([[1]], 1, (0,0)) → False
set_location([[None]], 1, (0,0)) → True # puzzle is now [[1]]
My code is the following:
def is_valid_location(loc,puzzle):
x,y=loc
return x in range(len(puzzle[0])) and y in range(len(puzzle))
def get_value_at_location(puzzle,loc):
val_loc=puzzle[loc[0]][loc[1]]
return val_loc
def set_location(puzzle,value,loc):
if is_valid_location(loc,puzzle)== True:
if get_value_at_location(puzzle,loc) != None:
return False
else:
if get_value_at_location(puzzle,loc) == None:
get_value_at_location(puzzle,loc)= value
return True
Obviously the problem is this line:
get_value_at_location(puzzle,loc)= value
But I'm not sure how else to do it. Any suggestions?
Would your solution be:
value = get_value_at_location(puzzle,loc)

Get boolean values as true or false instead 1 or 0

I'm using a MySql database, so I defined the column type as Tinyint(1) in db schema.
In my ActiveRecord I've set boolean validator. Save logic is working as expected.
What I wanted now is that when I call Yii2 REST service, return boolean field as true or false instead 1 or 0, because on the client side the framework comes with strict comparison (===) and 1 is not the same as true.
Of course I could overwrite the value manually before sending the content, or on the client side before loading it into the model, but I would appreciate a cleaner solution.
Inside afterFind i would modify the values from 0 or 1 to true or false:
public function afterFind() {
$this->booleanField = ($this->booleanField === 1);
parent::afterFind();
}

How can I create a default boolean value for a configuration using BND

I am using BND annotations to assist with creating a configuration managed by OSGI cm.
Here is my simple config
#Meta.AD(required = false, type = Type.Boolean, deflt = "false")
boolean enabled();
I have used the BND configuration annotation library quite a few times, but this is the first time that I would like to use a boolean type.
I have read through this
And it talks about an integer or other alternative number based handling of booleans for convenience. The thing is the deflt method always returns a string value, if my type was an integer I would do "2" (these are parsed). But booleans don't seem to be parsed in the configurable BND code up to this assignment point.
if (resultType == boolean.class || resultType == Boolean.class) {
if ( actualType == boolean.class || actualType == Boolean.class)
return o;
if (Number.class.isAssignableFrom(actualType)) {
double b = ((Number) o).doubleValue();
if (b == 0)
return false;
else
return true;
}
return true;
I would like to further know why this returns true when the deflt value is never even parsed. I expected this to more closely follow the spec and return false, since cm would try to do Boolean.parseFrom, so anything not "true" equal ignore case is false.
All of this isn't a complete failure because if I change the value through cm it works correctly after setting to true, and then false again, but obviously that was just an effort at wondering if it would ever work.
Simply I would like to know if anyone knows how to set a BOOLEAN default value using BND's configuration annotations.
Thanks