Sorry if this seems like a really stupid question. I am building an app using Django, and at some point I am accessing the db using db.objects.get(var = val)
But my question is what type object does this method return? And hw can I access the data in it?
Like as a dict, list or sth else?
When I use this:
a = db.objects.get(var=val)
print(a["id"])
It returns:
'db' object is not subscriptable
When I use this:
a = db.objects.get(var=val)
print(a)
I get:
db object (1)
I cannot use the data in this form.
It will return a object. See the docs for details.
Use . operator to access values inside object.
print(a.field_name)
It would return the object of your model on which you are querying.
If nothing matches and no rows is returned, it would through a Model.DoesNotExists exception.
Related
I'm pretty new in Python and SQLAlchemy, so basically I changed from:
session = Session()
session.query(SOMETHING_HERE).filter()
to
session = Session()
nested_session = session.begin_nested()
nested_session.query(SOMETHING_HERE).filter()
in order to use SAVEPOINTS. But I'm getting the error:
AttributeError: 'SessionTransaction' object has no attribute 'query'
I did a deep dive in the documentation, like these:
https://docs.sqlalchemy.org/en/13/orm/session_api.html#sqlalchemy.orm.session.SessionTransaction
https://docs.sqlalchemy.org/en/13/orm/session_transaction.html
But it did not help me.
Questions: Am I able to use begin_nested to run query with filter like that or I need to change the approach? Is this a version issue (sql alchemy for example)?
This was originally posted as a comment.
You don't need to reassign the result of session.begin_nested() to anything, you can just do: session.begin_nested() and then proceed with session.query(SOMETHING_HERE).filter()
Reference for this assertion: https://docs.sqlalchemy.org/en/13/orm/session_transaction.html#using-savepoint
#property
def returns_an_int(self):
some_var = do_something_that_returns_int()
if some_var:
return int(some_var)
else:
return 0
I have a property using the code above, which is supposed to (and does) return an int. (I put the int casting on it to double check) However when I try to use it to order a fetch,cls.query().order(cls.returns_an_int) I get a type error TypeError: order() expects a Property or query Order; received <property object at 0xsome-hex-address> - I have tried using + or - to see if I can make it get a value because I saw it in other questions but it didn't work. What am I doing wrong? Am I missing something basic to make it work?
When you query the datastore, you need to query on one of the various ndb.Property types. You are querying on a vanilla python property. This doesn't work because the python property data never gets stored in the datastore and so the datastore can't order by data that it doesn't know about.
It's hard to give definitive advice on how to fix this. You can do your query without the .order and sort in client code:
return sorted(cls.query(), key=lambda item: item.returns_an_int)
but that won't work for entity types that have lots of entities. You could also change your property to an ndb.ComputedProperty:
#ndb.ComputedProperty
def returns_an_int(self):
some_var = do_something_that_returns_int()
if some_var:
return int(some_var)
else:
return 0
The downside here is that you're storing (and paying for) more datastore data and you also execute the returns_an_int method for every datastore put. If it is a fast method to execute, that shouldn't be a problem, but if it is a slow method you might start to notice the difference.
I have a problem about insert function. If i have a array of objects to insert[bad,good,good]. if the first object is bad, and object insert action will fail, then the rest of the objects will never hit the database even the object is good.
How can i deal with it ?
You can validate the model instances before saving to ensure they are valid eg:
valid_docs = [d for d in docs if d.validate()]
Or pass in the continue_on_error=True as a write_options eg:
Doc.objects.insert(docs, write_options={"continue_on_error": True})
I am trying to check if the session does have anything in it. What I did is:
if request.session:
# do something
but it is not working. Is there any way of knowing whether the session contains something at that moment?
If I do request.session['some_name'], it works, but in some cases, I just need to know if the session is empty or not.
Asking with some specific names is not always a wanted thing.
Eg. if there is no session, it returns an error, since some_name doesn't exist.
request.session is an instance of SessionBase object which behaves like dictionary but it it is not a dictionary. This object has a "private" field ( actually it's a property ) called _session which is a dictionary which holds all data.
The reason for that is that Django does not load session until you call request.session[key]. It is lazily instantiated.
So you can try doing that:
if request.session._session:
# do something
or you can do it by looking at keys like this:
if request.session.keys():
# do something
Note how .keys() works:
django/contrib/sessions/backends/base.py
class SessionBase(object):
# some code
def keys(self):
return self._session.keys()
# some code
I always recommend reading the source code directly.
Nowadays there's a convenience method on the session object
request.session.is_empty()
To retrieve a django object, I am using the filter function as follows:
product = Product.objects.filter(code=request.POST['code'])
Then, when I try to access the retrieved object as:
product[0].description
I get an exception "list index out of range". Although, the filter is indeed returning an object because the len(product) call is showing "1".
However, if I hardcode the code value (retreived from the post above), I get no exception.
All I want to do is get access to the product object based on the code.
Using Product.objects.get does not work either...
Any help will be appreciated.
Thanks in advance.
You should probably validate that request.POST['code'] is valid before you try to use it in anything:
# code will be None if it isn't found in request.POST
code = request.POST.get('code')
if code:
products = Product.objects.filter(code=code)
for product in products:
print product.description
Hope this helps a bit.
It's not an answer but in this type of case, where the results make no sense, it's normally time to get the debugger out (either pdb or preferably ipdb).
import ipdb;ipdb.set_trace()
Then look at product. What actually is it? Look at request.POST['code'] and see what is different from just passing a literal. Also would be interested to know what the attempt to use 'get' actually does. You say it doesn't work but what does it actually do?