SQLAlchemy - loading user by username - python

Just diving into pylons here, and am trying to get my head around the basics of SQLALchemy. I have figured out how to load a record by id:
user_q = session.query(model.User)
user = user_q.get(user_id)
But how do I query by a specific field (i.e. username)? I assume there is a quick way to do it with the model rather than hand-building the query. I think it has something with the add_column() function on the query object, but I can't quite figure out how to use it. I've been trying stuff like this, but obviously it doesn't work:
user_q = meta.Session.query(model.User).add_column('username'=user_name)
user = user_q.get()

I believe you want something like this:
user = meta.Session.query(model.User).filter_by(name=user_name).first()
Which is short for this:
user = meta.Session.query(model.User).filter(model.User.name=user_name).first()
Here's more documentation
If you change first() into one() it will raise an exception if there isn't a user (if you want to assert one exists).
I highly suggest reading through both Object Relational Tutorial as well as the and the SQL Expression Language Tutorial.

Related

web2py validating db model for group menbers

I am using web2py, and am trying to build a field for auth_user, that should be validated to be a member of a certain group. So, in the models/db.py I have added a field that tells who is the manager of the user:
auth.settings.extra_fields['auth_user']=[Field('manager', 'reference auth_user')]
Then I have set up to db.auth_user, db.auth_group and db.auth_membership to contain users that belong to group 'managers'
And what I would like now to achieve is to validate user input so, that the 'manager' field of the auth_user could contain only users from the group 'managers'. I have gone through quite a few variations, following is maybe closest to making sense in theory in my mind:
group_id = auth.id_group('managers')
all_users_in_group = db(db.auth_membership.group_id==group_id)._select(db.auth_membership.user_id)
db.auth_user.auditor.requires = IS_IN_DB(db, db(~db.auth_user.id.belongs(all_users_in_group)).select(db.auth_user.id))
But even that is failing with
<type 'exceptions.AttributeError'>('Table' object has no attribute 'managers')
A perfect solution to my problem would show in the drop down menu not auth_user.id, but auth_user.first_name concatenated with auth_user.last_name.
I have used similar code to the following and confirm that is works with web2py 2.17.2-stable+timestamp.2018.10.06.18.54.02 (Running on nginx/1.14.0, Python 3.6.7).The previous answer will not work for this version.
group_id = auth.id_group('managers')
user_rows = db(db.auth_membership.group_id == group_id)._select(db.auth_membership.user_id)
query = db(db.auth_user.id.belongs(user_rows))
db.auth_user.auditor.requires = IS_IN_DB(query, db.auth_user.id, '%(first_name)s %(last_name)s'
You have done it correctly in your answer, but you can improve it.
The first argument of the validator can be a database connection or a DAL Set. So you can pass
directly a db query as first argument, like this
query = db((db.auth_membership.group_id == auth.id_group('managers')) &
(db.auth_membership.user_id == db.auth_user.id))
db.auth_user.auditor.requires = IS_IN_DB(query, db.auth_user.id, '%(first_name)s %(last_name)s')
You can also write query like below:
query = db((db.auth_group.role == 'managers') &
(db.auth_membership.group_id == db.auth_group.id) &
(db.auth_membership.user_id == db.auth_user.id))
I actually managed to solve this, but I would definitely not call this elegant. Would there be more idiomatic way to do this in web2py? Following is what I added to models/db.py
group_id = auth.id_group('managers')
rows=db(db.auth_membership.group_id==group_id).select(db.auth_membership.user_id)
rset=set()
for r in rows:
rset.add(int((r.user_id)))
db.auth_user.auditor.requires = IS_IN_DB(db(db.auth_user.id.belongs(rset)), db.auth_user.id, '%(first_name)s %(last_name)s')

Django: Raw SQL with connection.cursor()

I am a complete newbie to Django. I need to perform the following query and use img.img_loc to populate a list of images in a template:
SELECT img.img_loc, author.surname, author.given_name, author.email
FROM image_full AS img
LEFT JOIN author_contact_zzz AS author ON img.pmcid = author.pmcid
WHERE img.pmcid = 545600
GROUP BY img.img_loc, author.email;
I read the documentations here: https://docs.djangoproject.com/en/1.10/topics/db/sql/
However, I do not understand where the function:
def my_custom_sql(self):
that they are talking about in the last section is supposed to go to (views.py ?) and what is 'self' in that case, since my view is not defined as a class.
Thanks!
That looks like a typo. There's no need for self there.
The code can go wherever you like, though.

Python - Tweepy - How to use lookup_friendships?

I'm trying to figure out if I'm following a user from which the streaming API just received a tweet. If I don't, then I want to follow him.
I've got something like:
def checkFollow(status):
relationship = api.lookup_friendships("Privacy_Watch_",status.user.id_str)
From there, how do I check if I follow this user already?
The lookup_friendships method will return everyone you follow each time you call it, in blocks of 100 users. Provided you follow a lot of people, that will be highly inefficient and consume a lot of requests.
You can use instead the show_friendship method, it will return a JSON containing information about your relationship with the id provided.
I cannot test it right now, but the following code should do what you want:
def checkFollow(status):
relation = api.show_friendship(source_screen_name=your_user_name, target_screen_name=status.user.id_str)
if relation.target.following: #I'm not sure if it should be "target" or "source" here
return True
return False

Best option for alternate/suggested search in Django

I have a Django app that searches for data from a model Classified and displays them using simple querysets based on the input term. This works perfectly and I've got no complains with this method.
However, if someone enters a term that returns no data, I would like to provide an option with alternate/suggested search.
Eg: Someone searches 'Ambulance Services' which doesn't return data. I'd like to suggest 'Ambulance' or 'Services' as alternate search options which may return data from the model depending on the data present in the model.
I Googled suggested search in django and it gave me options of Haystack/elastic search, etc which I'm not sure are really required since the search is across just one model.
Note: SO tells me that my question may be closed as it is subjective. If thats the case, please suggest where I can move it to. Thank you!
This is just an idea, but might work for you:
The user enters the search data: "Ambulance Services"
If the query inside the view returns nothing, redirect to the same view using your selected alternative search data, lets say "Ambulance", and a flag value thats saids the view you're preforming a suggested search.
You must have two things in consideration:
What if the alternate search don't returns anything either? You have to set a recursion limit here.
How I'm going to select the data of the alternate search? Well, thats another question about a completly different topic.
This is this idea in code:
def search(request, data, alternate=False, recursion_level=3):
result = Classified.objects.filter(some_filed=data)
if 0 == result.count() and 0 != recursion_level: # Conditions needed for perform alternate search.
new_data = select_new_data(data) # The logic inside this function is up to you.
r_level = recursion_level - 1 # Decreas recursion level.
return redirect('search', alternate=True, recursion_level=r_level) # Redirecting using view name, you can use others
# forms of redirection see link below for visit
# the Djando redirect API doc.
else:
return_data = {}
if alternate:
# You can use this flag in order to reflect
# to the user you have performed an alternate search.
# Example:
return_data["alternate"] = True
# Build your return data.
# and render.
#return render_to_template()
Django redirect doc: redirect
Haystack is, indeed, a great option, here you will find how to give 'spelling suggestions', you can see an example in this OS question/answer
No matter you have only one model, this tool is really great, simple to install /set up/use, and very flexible.
Perhaps this helps as well.

How to write a generative update in SQLAlchemy

I'm just using SQLAlchemy core, and cannot get the sql to allow me to add where clauses. I would like this very generic update code to work on all my tables. The intent is that this is part of a generic insert/update function that corresponds to every table. By doing it this way it allows for extremely brief test code and simple CLI utilities that can simply pass all args & options without the complexity of separate sub-commands for each table.
It'll take a few more tweaks to get it there, but should be doing the updates now just fine. However, while SQLAlchemy refers to generative queries it doesn't distinguish between selects & updates. I've reviewed SQLAlchemy documentation, Essential SQLAlchemy, stackoverflow, and several source code repositories, and have found nothing.
u = self._table.update()
non_key_kw = {}
for column in self._table.c:
if column.name in self._table.primary_key:
u.where(self._table.c[column.name] == kw[column.name])
else:
col_name = column.name
non_key_kw[column.name] = kw[column.name]
print u
result = u.execute(kw)
Which fails - it doesn't seem to recognize the where clause:
UPDATE struct SET year=?, month=?, day=?, distance=?, speed=?, slope=?, temp=?
FAIL
And I can't find any examples of building up an update in this way. Any recommendations?
the "where()" method is generative in that it returns a new Update() object. The old one is not modified:
u = u.where(...)

Categories

Resources