MongoDB / MongoEngine: ValidationError at / [ObjectId('53f466e60ffa5927709972e8')] is not a valid ObjectId - django

How do I get the actual string ID from ObjectId('53f466e60ffa5927709972e8')?
This is the line that causes the error
humans = [humanInstance[0].id]
Update: I did
humans = [str(humanInstance[0].id)]
and now I get
['53f466e60ffa5927709972e8'] is not a valid ObjectId
Why is this not a valid ObjectID, and how do I get one? :/

The good news is '53f466e60ffa5927709972e8' looks like a valid ObjectId string:
a valid ObjectId (12 byte binary or 24 character hex string)
src: PyMongo ObjectId
You can convert to string as you are doing or via:
"%s" % humanInstance[0]
Or to get a list use a comprehension:
["%s" human for human in humanInstance]
However, your error is because it expects humans to be an ObjectId or a convertible to an ObjectId (the string is fine) but you are providing a list!
['53f466e60ffa5927709972e8'] is not a valid ObjectId
Try setting humans = '53f466e60ffa5927709972e8' or changing your Document schema to be a ListField of ObjectIdFields or ReferenceFields

Related

store infinity in postgres json via django

I have a list of tuples like below -
[(float.inf, 1.0), (270, 0.9002), (0, 0.0)]
I am looking for a simple serializer/deserializer that helps me store this tuple in a jsonb field in PostgreSQL.
I tried using JSONEncoder().encode(a_math_function) but didn't help.
I am facing the following error while attempting to store the above list in jsonb field -
django.db.utils.DataError: invalid input syntax for type json
LINE 1: ...", "a_math_function", "last_updated") VALUES (1, '[[Infinit...
DETAIL: Token "Infinity" is invalid.
Note: the field a_math_function is of type JSONField()
t=# select 'Infinity'::float;
float8
----------
Infinity
(1 row)
because
https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-FLOAT
In addition to ordinary numeric values, the floating-point types have
several special values:
Infinity
-Infinity
NaN
yet, the json does not have such possible value (unless its string)
https://www.json.org/
value
string
number
object
array
true
false
null
thus:
t=# select '{"k":Infinity}'::json;
ERROR: invalid input syntax for type json
LINE 1: select '{"k":Infinity}'::json;
^
DETAIL: Token "Infinity" is invalid.
CONTEXT: JSON data, line 1: {"k":Infinity...
Time: 19.059 ms
so it's not the jango or postgres limitation - just Infinity is invalid token, yet 'Infinity' is a valid string. so
t=# select '{"k":"Infinity"}'::json;
json
------------------
{"k":"Infinity"}
(1 row)
works... But Infinity here is "just a word". Of course you can save it as a string, not as numeric value and check every string if it's not equal "Infinity", and if it is - launch your program logic to treat it as real Infinity... But in short - you can't do it, because json specification does not support it... same asyou can't store lets say red #ff0000 as colour in json - only as string, to be caught and processed by your engine...
update:
postgres would cast float to text itself on to_json:
t=# select to_json(sub) from (select 'Infinity'::float) sub;
to_json
-----------------------
{"float8":"Infinity"}
(1 row)
update
https://www.postgresql.org/docs/current/static/datatype-json.html
When converting textual JSON input into jsonb, the primitive types
described by RFC 7159 are effectively mapped onto native PostgreSQL
types
...
number numeric NaN and infinity values are disallowed

Parse or get multiple key dictionary data from GET request

Datatables is sending to Django the following query string parameters:
action:remove
data[1][DT_RowId]:1
data[1][volume]:5.0
data[1][coeff]:35
data[2][DT_RowId]:2
data[2][volume]:4.0
data[2][coeff]:50
I can access the values like this:
print request.GET['data[1][volume]']
5.0
How can I access the key itself as a dictionary and its keys?
For example, I would like to access the value as data[1]['volume']. In addition, I need to access the keys; e.g. get 1 from data[1].
I think you will need to parse the keys, yourselves and convert them to dictionary. This could be done quickly using the regular expression module in python.
import re
pattern = re.compile("data\[(?P<key_one>.*?)\]\[(?P<key_two>.*?)\]")
match = pattern.match('data[1][volume]')
key_one = match.group('key_one')
key_two = match.group('key_two')
print(key_one) # Should print 1
print(key_two) # Should print volume
See Python documentation of its regular expression library to learn more.

Python, Using repeated field in API

I have an API presented as follow. If the API is called with only one value in params (which is a repeated field), everything work as intended. But if params holds multiple values, then I get error : No endpoint found for path.
1 INPUT = endpoints.ResourceContainer(
2 params = messages.IntegerField(1, repeated = True, variant = messages.Variant.INT32))
3
4 #endpoints.method(INPUT,
5 response_type.CustomResponse,
6 path = 'foo/{params}',
7 http_method = 'POST',
8 name = 'foo')
9 def foo(self, request):
10 #foo body is irrelevent
11 return response
How can I fix this. Something like : path = 'foo/{params[]}', ?
Thank you for your help
If 'params' is expected as part of the query string and not the path, you can just omit it from the path eg:
path = 'foo'
or
path = 'myApi/foo'
The example given in the docs uses a ResourceContainer for a single non-repeated path argument. Given the nature of repeated properties it doesn't look like you can use them as path arguments, only query string arguments. A repeated field in a query string would look like this (easily to deal with):
POST http://app.appspot.com/_ah/api/myApi/v1/foo?param=bar&param=baz ...
But a repeated field in a path argument would look like this (not so much):
POST http://app.appspot.com/_ah/api/myApi/v1/foo/bar/baz....

python insert to postgres over psycopg2 unicode characters

Hi guys I am having a problem with inserting utf-8 unicode character to my database.
The unicode that I get from my form is u'AJDUK MARKO\u010d'. Next step is to decode it to utf-8. value.encode('utf-8') then I get a string 'AJDUK MARKO\xc4\x8d'.
When I try to update the database, works the same for insert btw.
cur.execute( "UPDATE res_partner set %s = '%s' where id = %s;"%(columns, value, remote_partner_id))
The value gets inserted or updated to the database but the problem is it is exactly in the same format as AJDUK MARKO\xc4\x8d and of course I want AJDUK MARKOČ. Database has utf-8 encoding so it is not that.
What am I doing wrong? Surprisingly couldn't really find anything useful on the forums.
\xc4\x8d is the UTF-8 encoding representation of Č. It looks like the insert has worked but you're not printing the result correctly, probably by printing the whole row as a list. I.e.
>>> print "Č"
"Č"
>>> print ["Č"] # a list with one string
['\xc4\x8c']
We need to see more code to validate (It's always a good idea to give as much reproducible code as possible).
You could decode the result (result.decode("utf-8")) but you should avoid manually encoding or decoding. Psycopg2 already allows you send Unicodes, so you can do the following without encoding first:
cur.execute( u"UPDATE res_partner set %s = '%s' where id = %s;" % (columns, value, remote_partner_id))
- note the leading u
Psycopg2 can return Unicodes too by having strings automatically decoded:
import psycopg2
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
Edit:
SQL values should be passed as an argument to .execute(). See the big red box at: http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters
Instead
E.g.
# Replace the columns field first.
# Strictly we should use http://initd.org/psycopg/docs/sql.html#module-psycopg2.sql
sql = u"UPDATE res_partner set {} = %s where id = %s;".format(columns)
cur.execute(sql, (value, remote_partner_id))

Django - coercing to Unicode

I am having a unicode problem and, as everytime I have something related I'm completely lost..
One of my Django template renders a TypeError :
Exception Value:
coercing to Unicode: need string or buffer, long found
The line giving trouble is just a string ( which I want to use in a mysql query) :
query = unicode('''(SELECT asset_name, asset_description, asset_id, etat_id, etat_name FROM Asset LEFT OUTER JOIN Etat ON etat_id_asset=asset_id WHERE asset_id_proj='''+proj+''' AND asset_id_type='''+t.type_id+''' ORDER BY asset_name, asset_description) UNION (SELECT asset_name, asset_description, asset_id, 'NULL', 'NULL' FROM Asset WHERE asset_id_proj='''+proj+''' AND asset_id_type='''+t.type_id+''' AND asset_id IN (SELECT etat_id_asset FROM Etat)); ''')
What can be wrong here ?
I know you figured out a better way to accomplish, but to answer the original question, in case you get that error again somewhere else in the project:
t.type_id appears to be a long integer. You cannot mix integers in strings unless you convert to string, this is really simple:
myString = 'some string with type id ' + str(t.type_id) + ', and whatever else you want in the string.'