Flask SQLAlchemy does not commit until App ends - sqlalchemy

I've started my session like so:
from flask.ext.sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://mydatabase'
db = SQLAlchemy(app)
And I'm Adding entries to my database like so:
db.session.add(user(name, password))
db.session.commit()
Immediately after I add it, I render a new template. When the template's rendered, it should include the data I've just added, but it doesn't. However, when I end my app with a ctrl-c, then restart it, the data I've added now shows.
The data is submitted using a GET. The arguments are obtained using flask.request.args.get and it gets the name and password. Then the data is added using the db.session.add thing above.
After the db.session.add is done, the data is obtained from the entire database like so:
users = []
for userentry in user.query.all():
users.append(userentry.name)
In the template:
{% for name in users %}
<p>{{name}}</p>
{% endfor %}
Then template is rendered using: return render_template('my_page.html', users=users)

It seems I've been using an older design pattern that I found on the Flask Mega Tutorial. I solved my problem by opening up individual sessions for adding data. http://docs.sqlalchemy.org/en/rel_0_7/orm/session.html

Related

ProgrammingError at /user_booking not all arguments converted during bytes formatting

The idea is to display user's booking information like booking_name, package etc. I am fetching the data from database in my views.py like this.
def user_booking(request):
id = request.session['u_id']
booking_data = Booking.objects.raw('select * from booking WHERE id = %s',id)
return render(request,'user_booking.html',{'view_data':booking_data})
Now in user_booking.html is displaying data. I have used a proper template to display data in tabular format. Problem is when some data is returned from data base it works perfect. When there is a query for which no data can be found the page breaks and shows
"ProgrammingError at /user_booking not all arguments converted during bytes formatting"
Instead of all the formatting I resorted to basic code which looks like this
<html>
{% for b in view_data %}
{{b.b_name}}
{% endfor %}
</html>
It gives me the name "ajay" as output and does not break the page, also note that record for ajay's ID is present in my database. Now if ID is changed and then I refresh the lage again it gives me error.
What I am trying to do is if there is any data coming from the database then display it otherwise just display "no data here" msg.
How do I achieve it?

Queries in query set group in to one query using Django

I have a query set like the below.
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},
{'user':'abc','id':13,'home':'def','mobile':1233},
{'user':'abc','id':13,'home':'def','mobile':1555},]>
This QuerySet is returned by django using
users.objects.all()
For Each query in the query set, I'm drawing a user table in the front-end which shows the details of users. If the same 'user' registers with two 'mobile' numbers, it is showed as two rows in the table instead of one. My goal is to display two numbers in the same row instead of creating two rows.
I have thought of two possible solutions which are below:
Solution 1: I have thought of merging the two queries into one if the 'user' value matches in both the queries. For this we need to make lot of checks using conditional statements which works slowly when lot of users are there.
Solution 2: I have searched on Google and came up with Group By Django, but it is not working. I have tried below
query = users.objects.all().query
query.group_by = ['mobile']
results = QuerySet(query=query, model=users)
Please provide a way so that two queries can be clubbed into one based on 'user' and after clubbing 'mobile' should contain two values.
Edit: I will pass this query set to a template via view where the table is being drawn. At present, for each query, one row is the in table. Since the above query set has four queries, we will have four rows. But I want to display the information in just two rows since the 'id' and 'user' are same. Code for template is below:
{% if users %}
{% for user in users %}
{% for k,v in required_keys.items %}
<td>{{ user | get_item:k }}
{% endfor %}
{% endfor %}
{% endif %}
Required key is an dictionary which contains the keys which are used to display in table. Example:
Required_keys = {
'User Name':user,
'Contact':mobile,
'Address':home,
}
The get item is a function which gets the value when key is passed.
def get_item(dictionery,key):
return dictionery.get(key)
Edit 2: I have tried for a solution and it's not a full solution but it partially solves the problem. The solution perfectly works with one user. However if there are many users, the solution doesn't work. See below for example:
# input query set to the function which partially solves the problem
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},]>
# Now our team has written a function which gives the following output
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234,4321},]>
But if there are more than one user, the output is same as input, it doesn't club the queries. See the function below:
def merge_values(cls,values):
import itertools
grouped_results = itertools.groupby(values,key=lambda x:x['id'])
merged_values = []
for k,g in grouped_results:
groups=list(g)
merged_value = {}
for group in groups:
for key, val in group.iteritems():
if not merged_value.get(key):
merged_value[key] = val
elif val != merged_value[key]:
if isinstance(merged_value[key], list):
if val not in merged_value[key]:
merged_value[key].append(val)
else:
old_val = merged_value[key]
merged_value[key] = [old_value, val]
merged_values.append(merged_value)
return merged_values
The values parameter for the function is the whole query set. But this function
works if there is only one user in query set as mentioned above. But if there
are multiple users, it fails.
Edit 3: I have found why above function won't work for multiple users(don't know whether this is correct). The input query set to the function (for one user) is
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':12,'home':'qwe','mobile':4321},]>
Since the two user queries are one after another, they are clubbed. But if there are multiple users, the query set passed to the function is
<QuerySet[{'user':'xyz','id':12,'home':'qwe','mobile':1234},
{'user':'xyz','id':13,'home':'qwe','mobile':4321},
{'user':'abc','id':12,'home':'def','mobile':1233},
{'user':'abc','id':13,'home':'def','mobile':1555},]>
In the above query set, the user with same id are not one after another, so the function failed to get desired output.
You can use the function which you have written, only change is required is need to order the values based on id.
So before taking the values from the objects, order_by('id'), then take your required values and pass it to your function to merge the values.
Eg.
query_set = Mymodel.objects.filter(name='Required').order_by('id')
values = query_set.values('id', 'field1', 'field2')
merged_values = merge_values(values)
As a start, what would be helpful is to organise your models better. You have user information duplicated in your user model. If a you know that a user has multiple mobile numbers, it may be better to create a separate model for that:
class Mobile(models.Model)
number = models.IntegerField()
user = models.ForeignKey(User)
Then, when you are make a query and you want to get all the mobile numbers, you would first get all the users using users = User.objects.all() in your view, then in your template:
{% for user in users %}
{% for mobile in user.mobile_set.all %}
<td>{{ user }}</td>
<td>{{ mobile.number }}</td>
{% endfor %}
{% endfor %}
As a side note, I feel it's better practice to name your models as a singular (User instead of Users)

Can I allow paging in the contenttype config

I have been playing with the paginator function in Bolt CMS, it is easy to use.
Now I need to know if there is a way to implement the pagination in the contenttype yaml.
I think, is it possible something like this?
entries:
name: Entries
singular_name: Entry
fields:
...
taxonomy: [ categories ]
allowpaging: true
I only have found that you need explicity write the allowpaging flag when you fetch the content via setcontent:
{% setcontent entries = "entries/latest/4" allowpaging %}
But what if you want to use the same template for displaying the related taxonomy records? The problem is that you always will be fetching the last 4 entries regardless the taxonomy.
If there's no way to do this, there would be a way to implementing it?
Paging will also be automatically set if you use listing records setting
listing_records: 10
But your template still needs a pager that will use this setting - the listing templates in the theme/base-2014 will work and can be used as an example
The docs have more information https://docs.bolt.cm/contenttypes-and-records#defining-contenttypes
In config.yml set listing_records: xx or the number of records you want to show
then set in your .twix template {% setcontent entries = "entries/latest/xx" allowpaging %}with the same number
and add at the end of .twix file put this code {{ pager('pages') }} to show pages
You can see the official bolt docs for further informations
https://docs.bolt.cm/3.1/templating/content-paging

Django - Add rows to MySQL database

So I already have a database setup with a few columns and a few rows already inserted in. I'm trying to create a view that you would just input information into a form and press Submit, then a row would be added to the MySQL database with the information you just typed in.
I believe you can do this with admin, but I would like to try without admin and I'm not sure if this is possible? I've been using the MySQL commandline to add rows as of now..
Of coures this is possible this is a building block for data driven websites. You can use a ModelForm as Daniel suggested (they offer built in validation and HTML markup for FREE) to easily map your model to a front end form. It would probably be beneficial to start with django tutorial or documentation first.
At the the very basic, all you have to do is instantiate your model
new_entry = YourModel(name='me', age='222', about='stackoverflow')
then save it
new_entry.save()
This adds it as a new row to your db.
https://docs.djangoproject.com/en/dev/topics/db/models/
Why would it not be possible?
You probably want a modelform (but see the general form introduction first).
Try out this example of Generic Views: http://postneo.com/2005/08/17/django-generic-views-crud (assumes a model named Task)
With Generic Views you get Insert, Update and Delete for free without any real work. give it a try and let me know what you think.
from django.conf.urls.defaults import *
info_dict = {
'app_label': 'tasks',
'module_name': 'tasks',
}
urlpatterns = patterns('',
(r'^tasks/create/?$', 'django.views.generic.create_update.create_object', info_dict ),
(r'^tasks/update/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.update_object', info_dict),
(r'^tasks/delete/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.delete_object', info_dict ),
)
Django Docs: https://docs.djangoproject.com/en/1.2/ref/generic-views/#create-update-delete-generic-views

Expense of django query

I have two tables: Actor and Images. The Images table is linked to the Actor table through a Foreign Key. I might make a query on Actor that pulls a list of all the actors with first name beginning with the letter A. Let's say I store this query result in actor_list and pass it to the template. I can get a list of all the Images through the template by iterating. Something like:
{% for actor in actor_list %}
{% for image in actor.img_set %}
{{ image }}
{% endfor %}
{% endfor %}
Is this costly to the database? Does the associated img_set come through with the initial actor object list, or does a new query hit the database every time I call for the actor.img_set?
You should install the Django debug toolbar and see what SQL queries are happening under the covers.
If you are getting too many queries, you can try using select_related() to pull in the related data in the initial query.
Better than using the django toolbar is using the connections library. With Debug set to True:
>>> from django.db import connection
>>> for actor in actor_list:
>>> for image in actor.img_set:
>>> image
>>> connection.queries()
This will show all the queries that were executed and the amount of time that each took.
The debug toolbar is cool, though, for many uses. :-)