What does this construct in Pyramid mean? - python

Construction from pyramid docs
#classmethod
def all(cls, request):
query = request.dbsession.query(BlogRecord)
return query.order_by(sa.desc(BlogRecord.created))
I don't understand what's going on in this statement.
query = request.dbsession.query(BlogRecord)
As I understand we create an example of a query class, but what do we get from:
query(BlogRecord) inheritance from BlogRecord?
request.dbsession.query I have no idea.

Assuming you walked through all the previous steps in the tutorial including 1. Create your pyramid_blogr project structure and Adding model definitions, you would know that BlogRecord is an object or an instance of the class BlogRecord which inherits from the SQLAlchemy metadata Base class defined in models.meta which was created using the alchemy cookiecutter. This line:
query = request.dbsession.query(BlogRecord)
creates a variable query and assigns a database query object as its value. It does not execute the query yet. The next line does that, and returns the result.
Going further, taking apart request.dbsession.query, the request portion is a request object that is passed around in Pyramid. Attributes can be attached to the request object, in this case the dbsession object (an SQLAlchemy database session object) is the attribute. This in turn has a method named query which accepts a data model as its argument.
This is mostly Python stuff regarding classes and methods, and not specific to Pyramid. I'd suggest reading more about those in the Python documentation and tutorials.
Note: the answer from #not_a_bot_no_really_82353 is completely wrong. Pyramid does not use the requests (plural) library. Pyramid has a request (singular) object. Also the "docs" are a community-contributed tutorial, not documentation. For official documentation and tutorials, visit https://docs.pylonsproject.org/projects/pyramid/en/latest/index.html

Related

Flask-Login current_user changing to the most recent User class query result

My implementation of Flask-Login is working well across my site, with the exception of contexts where I need to make additional queries on the User class. For example, when I try to generate a list of User instances representing other users with whom the current_user shares a task, the values stored in current_user are rewritten each time a new instance of User is created. In addition, the attributes of each of the other previously-generated User instances are also overwritten, with the exception of the User.id attribute, which remains unique (and correct).
I am using pyAirtable as an ORM between Flask and an Airtable base containing user data. The ORM is experimental and built using abstract base classes. I wonder whether this issue may be due to a conflict between instance and class variables.
I specifically suspect the _fields variable may be the culprit, because it appears as both a class variable and an instance variable in the source for the base Model. (The issue may also be with the from_id() method, which I use in a list comprehension to generate the aforementioned list of User instances from a list of Airtable record IDs.) However, I'm not experienced enough with ABCs or Python to be able to determine this for sure. I've tried fiddling with the pyairtable package for debugging, to no avail.
What am I missing? Is this an issue with pyairtable, flask-login, an unexpected interaction between the two packages, or just my implementation?

Choosing from a populated table in factory boy while using flask

In factory boy it is possible to create a sqlalchemy object with a relationship to another table. There is a common recipe for Choosing from a populated table which is made for django, and I want to do this now for flask.
So I'd think that I have use this line.
user = factory.Iterator(User.query.all())
But of course it doesn't work. I get an error that there is no application context. It states in the documentation that the query wont be evaluated until the first call to to the Userfactory, however the error occurs when importing.
I want to have a factory that chooses the foreign key from an object that I already created. How can I do this in flask?
The example works for Django because a QuerySet is lazy; i.e. the request only hits the database when trying to iterate on it.
FactoryBoy's Iterator will only start iterating on the provided generator when the first factory call is made.
For SQLAlchemy, you need a way to return a generator instead of a list; I think this would work with factory.Iterator(User.query).
User.query.all() explicitly sends the SQL request and retrieves the results, which will fail before the app is properly configured.
If that doesn't work (the SQLAlchemy docs aren't very clear on the Query iteration behaviour), you could try with a helper function:
def lazy_users():
"""Turn `User.query.all()` into a lazily evaluated generator"""
yield from User.query.all()
class ProfileFactory(...):
user = factory.Iterator(lazy_users())

executing django model query?

In django model query, i want to know the sequential execution of it. Consider a query Blog.objects.get(name='palm').
In this where the Blog is defined, is that same as class blog in models.py?
What is objects i can't find anything related to this in source files of django. If Blog is a class, then what is the type of objects?
I want a development side concept. Can any one please explain how django makes these possible?
Every non-abstract Django model class has an attribute objects attached to it (unless you of course explicitly remove it).
object is a Manager. It is an object that has a lot of methods to construct queries that are then send to the database to fetch/store data.
So you first access the objects manager of the Blog class, next you call .get(name='palm') on it. This means that Django will translate this into a query. This depends on the database system you use. For instance if it is MySQL it will look like:
SELECT name, some, other columns
FROM app_blog
WHERE name = 'palm'
The database will respond with zero, one or more rows, and Django will, in case no or more than one row is found, raise a DoesNotExists or MultipleObjectsReturned error. Otherwise it will load the data into a Blog object (by deserializing the columns into Python objects).

Mocking a Django Queryset in order to test a function that takes a queryset

I have a utility function in my Django project, it takes a queryset, gets some data from it and returns a result. I'd like to write some tests for this function. Is there anyway to 'mock' a QuerySet? I'd like to create an object that doesn't touch the database, and i can provide it with a list of values to use (i.e. some fake rows) and then it'll act just like a queryset, and will allow someone to do field lookups on it/filter/get/all etc.
Does anything like this exist already?
For an empty Queryset, I'd go simply for using none as keithhackbarth has already stated.
However, to mock a Queryset that will return a list of values, I prefer to use a Mock with a spec of the Model's manager. As an example (Python 2.7 style - I've used the external Mock library), here's a simple test where the Queryset is filtered and then counted:
from django.test import TestCase
from mock import Mock
from .models import Example
def queryset_func(queryset, filter_value):
"""
An example function to be tested
"""
return queryset.filter(stuff=filter_value).count()
class TestQuerysetFunc(TestCase):
def test_happy(self):
"""
`queryset_func` filters provided queryset and counts result
"""
m_queryset = Mock(spec=Example.objects)
m_queryset.filter.return_value = m_queryset
m_queryset.count.return_value = 97
result = func_to_test(m_queryset, '__TEST_VALUE__')
self.assertEqual(result, 97)
m_queryset.filter.assert_called_once_with(stuff='__TEST_VALUE__')
m_queryset.count.assert_called_once_with()
However, to fulfil the question, instead of setting a return_value for count, this could easily be adjusted to be a list of model instances returned from all.
Note that chaining is handled by setting the filter to return the mocked queryset:
m_queryset.filter.return_value = m_queryset
This would need to be applied for any queryset methods used in the function under test, e.g. exclude, etc.
Of course you can mock a QuerySet, you can mock anything.
You can create an object yourself, and give it the interface you need, and have it return any data you like. At heart, mocking is nothing more than providing a "test double" that acts enough like the real thing for your tests' purposes.
The low-tech way to get started is to define an object:
class MockQuerySet(object):
pass
then create one of these, and hand it to your test. The test will fail, likely on an AttributeError. That will tell you what you need to implement on your MockQuerySet. Repeat until your object is rich enough for your tests.
I am having the same issue, and it looks like some nice person has written a library for mocking QuerySets, it is called mock-django and the specific code you will need is here https://github.com/dcramer/mock-django/blob/master/mock_django/query.py I think you can then just patch you models objects function to return one of these QuerySetMock objects that you have set up to return something expected!
For this I use Django's .none() function.
For example:
class Location(models.Model):
name = models.CharField(max_length=100)
mock_locations = Location.objects.none()
This is the method used frequently in Django's own internal test cases. Based on comments in the code
Calling none() will create a queryset that never returns any objects and no
+query will be executed when accessing the results. A qs.none() queryset
+is an instance of ``EmptyQuerySet``.
Try out the django_mock_queries library that lets you mock out the database access, and still use some of the Django query set features like filtering.
Full disclosure: I contributed some features to the project.
Have you looked into FactoryBoy? https://factoryboy.readthedocs.io/en/latest/orms.html
It's a fixtures replacement tool with support for the django orm - factories basically generate orm-like objects (either in memory or in a test database).
Here's a great article for getting started: https://www.caktusgroup.com/blog/2013/07/17/factory-boy-alternative-django-testing-fixtures/
One first advice would be to split the function in two parts, one that creates the queryset
and one that manipulates the output of it. In this way testing the second part is straightforward.
For the database problem, I investigated if django uses sqlite-in-memory and I found out that
recent version of django uses the sqlite -in-memory database, from The django unittest page:
When using the SQLite database engine the tests will by default use an
in-memory database (i.e., the database will be created in memory,
bypassing the filesystem entirely!).
Mocking the QuerySet object will not make you exercise its full logic.
You can mock like this:
#patch('django.db.models.query.QuerySet')
def test_returning_distinct_records_for_city(self, mock_qs):
self.assertTrue(mock_qs.called)
Not that I know of, but why not use an actual queryset? The test framework is all set up to allow you to create sample data within your test, and the database is re-created on every test, so there doesn't seem to be any reason not to use the real thing.

Is it possible to update an entry on Google App Engine datastore through the object's dictionary?

I tried the following code and it didn't work:
class SourceUpdate(webapp.RequestHandler):
def post(self):
id = int(self.request.get('id'))
source = Source.get_by_id(id)
for property in self.request.arguments():
if property != 'id':
source.__dict__[property] = self.request.get(property)
source.put()
self.redirect('/source')
I am posting all the necessary properties but the entry isn't updated, and no error is shown. How to fix it?
BTW
class Source(db.Model):
#some string properties
You're bypassing the __setattr__-like functionality that the models' metaclass (type(type(source))) is normally using to deal with attribute-setting properly. Change your inner loop to:
for property in self.request.arguments():
if property != 'id':
setattr(source, property, self.request.get(property))
and everything should work (if all the types of properties can be properly set from a string, since that's what you'll get from request.get).
Instead of directly setting model values from the request, you might want to look into using Django forms. They're bundled with App Engine, and facilitate validating form data and storing it in the datastore, as well as generating the form HTML. There's an article on how to use them with the App Engine datastore here.
Also, don't forget that making changes based on a GET request is almost always a bad idea, and leads to XSRF vulnerabilities and other problems!

Categories

Resources