Search document in MongoDB by _id using Flask-pymongo extension - python

I am baffled with the following problem.
I am using Flask, flask-pymongo extension, mongodb version v2.2.0-rc0, pdfile version 4.5
This is my route:
#app.route("/check/<id>")
def check(id):
doc=conn.db.msg.find_one({'_id':id})
return render_template('base.html',name=doc)
the id is a valid _id from a document in the msg collection, but ALWAYS return None.
I have tried:
pasing the ObjectId(id) but returns errortype: ObjectId not callable
pasing the id as str(id) returns None
Any thoughts?
UPDATE:
this how the full url looks like:
http://127.0.0.1:8000/check/5030b628895b800de1a9a792
UPDATE2:
I found a similar question with (answer) for ruby. Not sure how I can translate it to python, what sort imports/modules do I need?
How can I retrieve a document by _id?
UPDATE3:
I tried:
import bson
#app.route("/check/<id>")
def check(id):
id2="'"+id+"'"
doc=conn.db.msg.find_one({'_id':bson.objectid(id2) })
return render_template('base.html',name=doc)
but I get TypeError: 'module' object is not callable (it doesnt work with id either)
when I reached 1500 I will suggest a frustation tag :-S
UPDATE4:
Finally I got it up & running!
here it is my solution:
import bson
#app.route("/check/<id>")
def check(id):
doc=conn.db.msg.find_one({'_id':bson.ObjectId(oid=str(id))})
return render_template('base.html',name=doc)

You might also want to try using ObjectId from the bson.objectid module, like so:
from bson.objectid import ObjectId
In that case, you won't need to provide the oid kwarg. You'll just do something like this:
db_conn.msg.find_one({'_id': ObjectId(my_oid)})

Related

Pymongo UUID search not returning documents that definitely exist

Trying to define a function in python that can search for a given UUID like so:
def getid(in_id):
return list(CollectionVar.find({"_id":UUID(in_id)}))
And passing in a UUID. I can take a UUID I know exists from Studio 3T like so:
db.getCollection("CollectionName").find({"_id":UUID("5002aa11-eeb7-4e68-a121-dd51497d2572")})
And the above query returns precisely one document. That same UUID in the python query returns absolutely nothing. I can find documents on other (non UUID) fields easily enough, for example the following works fine on that same document from earlier:
def getname(fn,sn):
return list(CollectionVar.find({"Firstname":re.compile(fn, re.IGNORECASE), "Surname":re.compile(sn, re.IGNORECASE)}))
This seems like a problem with the uuid.UUID class rather than a pymongo issue? Can anyone see the problem?
PyMongo Version 3.6.1
The issue is that PyMongo uses a legacy method of encoding/decoding UUID values by default. You probably want to configure the PyMongo client to use the more modern, cross-language compatible "standard" UUID representation:
client = MongoClient(MONGODB_URI, uuidRepresentation="standard")
Now you should be able to query directly using Python uuid.UUID instances:
from uuid import UUID
items = client["item_database"]["items"].find_one({
"uuid": UUID("187382af-1369-43e6-a0ba-d345886c986c")
})
I've solved this. For anyone else who hits this issue the solution is below:
from bson.binary import Binary, UUID_SUBTYPE
def getcust(inid):
newuuid=uuid.UUID(inid).bytes
return list(DealershipConsumer.find({"_id": Binary(bytes(bytearray(newuuid)), UUID_SUBTYPE)}))
UUID_SUBTYPE needs to be set to whatever subtype of UUID you use - in my case it's 4.
You could specify the UUID type you're using when getting the db :
import bson
import pymongo
mongo_client = pymongo.MongoClient(mongo_uri, document_class=dict)
db = mongo_client.get_database(
"my_db_name",
bson.codec_options.CodecOptions(uuid_representation=bson.binary.UUID_SUBTYPE),
)
If you want to read more about Mongo best practices while using UUIDs, this article might help.
Also, here are the docs about codec_options
I've scraped this from pymongo-2.8.1 in the bson.binary.UUIDLegacy class's docstring/comment, might be usefull
>>> import uuid
>>> from bson.binary import Binary, UUIDLegacy, UUID_SUBTYPE
>>> my_uuid = uuid.uuid4()
>>> coll = db.test
>>> coll.uuid_subtype = UUID_SUBTYPE
>>> coll.insert({'uuid': Binary(my_uuid.bytes, 3)})
ObjectId('...')
>>> coll.find({'uuid': my_uuid}).count()
0
>>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
1
>>> coll.find({'uuid': UUIDLegacy(my_uuid)})[0]['uuid']
UUID('...')
>>>
>>> # Convert from subtype 3 to subtype 4
>>> doc = coll.find_one({'uuid': UUIDLegacy(my_uuid)})
>>> coll.save(doc)
ObjectId('...')
>>> coll.find({'uuid': UUIDLegacy(my_uuid)}).count()
0
>>> coll.find({'uuid': {'$in': [UUIDLegacy(my_uuid), my_uuid]}}).count()
1
>>> coll.find_one({'uuid': my_uuid})['uuid']
UUID('...')
You need to use ObjectId instead of UUID.
Try this, it works for me:
from bson.objectid import ObjectId
def getid(in_id):
return list(CollectionVar.find({"_id":ObjectId(in_id)}))

References from Python Bigquery Client don't work

Im having troubles running the following code:
from google.cloud import bigquery
client = bigquery.Client.from_service_account_json(BQJSONKEY,project = BQPROJECT)
dataset = client.dataset(BQDATASET)
assert not dataset.exists()
The following error pop up:
'DatasetReference' object has no attribute 'exists'
Similarly when i do:
table = dataset.table(BQTABLE)
i get: 'TableReference' object has no attribute 'exists'
However, according to the docs it should work:
https://googlecloudplatform.github.io/google-cloud-python/stable/bigquery/usage.html#datasets
here is my pip freeze (the part with google-cloud):
gapic-google-cloud-datastore-v1==0.15.3
gapic-google-cloud-error-reporting-v1beta1==0.15.3
gapic-google-cloud-logging-v2==0.91.3
gevent==1.2.2
glob2==0.5
gmpy2==2.0.8
google-api-core==0.1.1
google-auth==1.2.1
google-cloud==0.30.0
google-cloud-bigquery==0.28.0
google-cloud-bigtable==0.28.1
google-cloud-core==0.28.0
google-cloud-datastore==1.4.0
google-cloud-dns==0.28.0
google-cloud-error-reporting==0.28.0
google-cloud-firestore==0.28.0
google-cloud-language==1.0.0
google-cloud-logging==1.4.0
google-cloud-monitoring==0.28.0
google-cloud-pubsub==0.29.1
google-cloud-resource-manager==0.28.0
google-cloud-runtimeconfig==0.28.0
google-cloud-spanner==0.29.0
google-cloud-speech==0.30.0
google-cloud-storage==1.6.0
google-cloud-trace==0.16.0
google-cloud-translate==1.3.0
google-cloud-videointelligence==0.28.0
google-cloud-vision==0.28.0
google-gax==0.15.16
google-resumable-media==0.3.1
googleapis-common-protos==1.5.3
I wonder how can i fix it and make it work?
Not sure how you got to this docs but you should be using these as reference:
https://googlecloudplatform.github.io/google-cloud-python/latest/bigquery/usage.html#datasets
Code for 0.28 would be something like:
dataset_refence = client.dataset(BQDATASET)
dataset = client.get_dataset(dataset_reference)
assert dataset.created is not None
I think you forgot to create the dataset before calling exists()
dataset = client.dataset(BQDATASET)
dataset.create()
assert not dataset.exists()

Django Querying MongoDB ObjectIds in views from json object

I am currently working on querying MongoDB objects in Python Django and had no trouble in creating queries if it's the other attributes needed.
However I need to modify my queries to specifically filter through the ObjectIds returning one or no object found.
From my Javascript I am passing a json data to my Django views.py here's how it currently looks like:
def update(request):
#AJAX data
line = json.loads(request.body)
_id = line['_id']
print("OBJECT_ID: %s" % (_id))
another_id = line['another_id']
print("ANOTHER_ID: %s" % (another_id))
*Don't confuse the another_id, there are objects that has the same another_id s and unfortunately has to remain like that. That's why I can't query it for update since it will update all duplicates. This is the reason why I need the ObjectId.
For checking here's what it prints out:
{u'$oid': u'582fc95bb7abe7943f1a45b2'}
ANOTHER_ID: LTJ1277
Therefore I appended the query in views.py like this:
try:
Line.objects(_id=_id).update(set__geometry=geometry, set__properties=properties)
print("Edited: " + another_id)
except:
print("Unedited.")
But it didn't return any object.
So I was wondering if the query itself can't recognize the $oidin the json body as "_id" : ObjectId("582fc95bb7abe7943f1a45b2")?
*Edit:
from bson.objectid import ObjectId
where I edited my views.py with:
_id = line['_id']
print("VALUES: %s" % (_id.get('$oid')))
try:
Line.objects(_id=ObjectId(_id.get('$oid'))).update(set__geometry=geometry, set__properties=properties)
Output:
VALUES: 582fc95bb7abe7943f1a498c
No luck. Still not querying/not found.
According to this Using MongoDB with Django reference site:
Notice that to access the unique object ID, you use "id" rather than "_id".
I tried revising the code from:
Line.objects(_id=ObjectId(_id.get('$oid'))).update(set__geometry=geometry, set__properties=properties)
to
Line.objects(id=ObjectId(_id.get('$oid'))).update(set__geometry=geometry, set__properties=properties)
...And it now works fine. Keeping this question for others who might need this.

PyMongo error: cannot convert value of type to bson

I'm using flask with pymongo, and i have the error:
bson.errors.InvalidDocument
InvalidDocument: cannot convert value of type to bso
My code for this error is:
def get_question_with_id(id,question):
question = db.questions.find_one({'id': id})
return question,id
I searched for many hours for one solution, but i did not find answer for this problem.
what is this error?
from bson.objectid import ObjectId
def get_question_with_id(id,question):
question = db.questions.find_one({'_id':ObjectId(id)})
return question,id

Django - Haystack Query Serialization

I'm trying to serialize a HayStack SearchQuerySet:
from django.core import serializers
serializers.serialize("json", SearchQuerySet().filter(content=request.GET['q']))
but it throws:
'SearchQuery' object has no attribute '_build_query'
How can I fix this?
I don't recommend call 'object' per result as it would hit to database and beat purpose of search performance. Instead consider calling get_stored_fields method which can be used with json dumps:
import simplejson as json
data = map(lambda x: x.get_stored_fields(), search_result)
json.dumps(data)
I had faced a similar problem.
used something like this and it worked:
serializers.serialize("json", [x.object for x in queryset]

Categories

Resources