Can't get myself to do something as easy as good ol'
SELECT phrase.content, meaning.content
FROM phrase JOIN meaning
ON phrase.id = meaning.phrase_id
All the examples I can find in the documentation/SO are variations of
a = Phrase.query.join(Meaning).all()
which doesn't really work cause then a is a list of Phrase objects, whereas I want to select one attribute from Phrase and one from Meaning.
Anybody? Thanks
q = db.session.query(Phrase.content, Meaning.content).join(Meaning).all()
Related
I'm trying to find a regex expression in python that will be able to handle most of the UPDATE queries that I throw at if from my DB. I can't use sqlparse or any other libraries that may be useful with for this, I can only use python's built-in modules or cx_Oracle, in case it has a method I'm not aware of that could do something like this.
Most update queries look like this:
UPDATE TABLE_NAME SET COLUMN_NAME=2, OTHER_COLUMN=to_date('31-DEC-202023:59:59','DD-MON-YYYYHH24:MI:SS'), COLUMN_STRING='Hello, thanks for your help', UPDATED_BY=-100 WHERE CODE=9999;
Most update queries I use have a version of these types of updates. The output has to be a list including each separate SQL keyword (UPDATE, SET, WHERE), each separate update statement(i.e COLUMN_NAME=2) and the final identifier (CODE=9999).
Ideally, the result would look something like this:
list = ['UPDATE', 'TABLE_NAME', 'SET', 'COLUMN_NAME=2', 'OTHER_COLUMN=("31-DEC-2020 23:59:59","DD-MON-YYYY HH24:MI:SS")', COLUMN_STRING='Hello, thanks for your help', 'UPDATED_BY=-100', 'WHERE', 'CODE=9999']
Initially I tried doing this using a string.split() splitting on the spaces, but when dealing with one of my slightly more complex queries like the one above, the split method doesn't deal well with string updates such as the one I'm trying to make in COLUMN_STRING or those in OTHER_COLUMN due to the blank spaces in those updates.
Let's use the shlex module :
import shlex
test="UPDATE TABLE_NAME SET COLUMN_NAME=2, OTHER_COLUMN=to_date('31-DEC-202023:59:59','DD-MON-YYYYHH24:MI:SS'), COLUMN_STRING='Hello, thanks for your help', UPDATED_BY=-100 WHERE CODE=9999;"
t=shlex.split(test)
Up to here, we won't get rid of comma delimiters and the last semi one, so maybe we can do this :
for i in t:
if i[-1] in [',',';']:
i=i[:-1]
If we print every element of that list we'll get :
UPDATE
TABLE_NAME
SET
COLUMN_NAME=2
OTHER_COLUMN=to_date(31-DEC-202023:59:59,DD-MON-YYYYHH24:MI:SS)
COLUMN_STRING=Hello, thanks for your help
UPDATED_BY=-100
WHERE
CODE=9999
Not a proper generic answer, but serves the purpose i hope.
I'm currently using Python and LDAP to query Active Directory for users.
I have a list of names that are First Last. Not specific enough to find the exact user.
I would like a filter that would find all users matching 'Last, First*'
and belonging to any group with a keyword in it.
_filter = '''(& (objectclass=user)
(objectcategory=person)
(name={}*) )'''.format(search_string)
and I've tried adding...
(memberOf=CN=*Keyword*,OU=Delegated,OU=Groups,DC=amr,DC=corp,DC=xxxxxx,DC=com)
To my filter, but with no success.
If this was SQL, I would write something like:
Select *
From
Users
Where
Users.name like 'First, Last%'
and Users.memberOf like 'Keyword%'
Update:
After reviewing Gabriel's answer I'm running this.
def get_idsids(self, search_string):
_filter = '''(& (objectclass=user)
(objectcategory=person)
(anr={}) )'''.format(search_string)
# Search for user.
# Will return list of users matching criteria.
# The results are wrapped up as a list(tuple(dict))) where the dict vals are binary strings or lists of binary strings.
users = self.con.search_s(ActiveDirUser.BASEDN, ldap.SCOPE_SUBTREE, _filter, ['displayName', 'sAMAccountName', 'memberOf'])
# This line is ugly... It just converts the results to a list of ids
# So long as the user has at least one group with 'Keyword' in the name.
# upper() is used to make the Keyword requriement case insensitive.
return [user[1]['sAMAccountName'][0].decode() for user in users if 'KEYWORD' in ''.join(map(str, user[1]['memberOf'])).upper()]
I do wonder though, could I search for groups with 'Keyword' in the name and build filters from that? Further, would that be faster? I assume it would as AD probably hashes group membership.
I will go do some reading, but I assume group names are wildcard searchable?
I suggest you use Ambiguous Name Resolution:
_filter = '''(& (objectclass=user)
(objectcategory=person)
(anr={}) )'''.format(search_string)
Read that documentation to understand how it works, but it can find users if you give it a string of "first last". This is what the search box in AD Users and Computers uses.
Just be aware that you can get doubles if people have similar names. If you take my name for example: if you would search for "Gabriel Luci", and there was someone else with the name "Gabriel Luciano", you would find both of us.
This:
(memberOf=CN=*Keyword*,OU=Delegated,OU=Groups,DC=amr,DC=corp,DC=xxxxxx,DC=com)
doesn't work because you can't use wildcards on any attribute that is a distinguishedName, like memberOf.
That's for Active Directory anyway. Other LDAP directories might allow it.
If you need to check if the users are members of groups, then you can tell your search to return the memberOf attribute in the search (I don't know phython, but you should have a way of telling it which attributes you want returned). Then you can loop through the groups in the memberOf attribute and look for that keyword.
Let's say I have a list of people that can be "followed".
I'd like to iterate through all the people that a certain user is following and grab posts from all of those users in the form of a queryset.
I understand that I can combine querysets by using chain or |, but I'm a bit confused when it comes to combining querysets that I might grab from looping through everyone being followed.
following = UserFollows.objects.filter(user_id = user.id)
for follow in following.iterator():
UserPost.objects.filter(user=follow.user) #what do I do with this?
How would I combine those if I cant explicitly name them to chain or '|'?
You can do something like this:
following = UserFollows.objects.filter(user__id = user.id).select_related('user')
users_ids = [follow.user.id for follow in following]
posts = UserPost.objects.filter(user__id__in=users_ids)
but look that it is quite expensive operation so it's good to add select_related() method to fetch users in one query. I think you should also consider to cache the users_ids list before get it from database.
Have you tried something like
following = UserFollows.objects.filter(user_id = user.id)
q = UserPost.objects.filter(user=following[0].user)
for follow in following[1:]:
q = q | UserPost.objects.filter(user=follow.user)
I have a many to many relationship between two tables/objects: Tag and Content. Tag.content is the relationship from a tag to all content which has this tag.
Now I'd like to find out the number of content objects assigned to a tag (for all tags, otherwise I'd simply use len()). The following code almost works:
cnt = db.func.count()
q = db.session.query(Tag, cnt) \
.outerjoin(Tag.content) \
.group_by(Tag) \
.order_by(cnt.desc())
However, it will never return a zero count for obvious reasons - there is at least one row per tag after all due to the LEFT JOIN used. This is a problem though since I'd like to get the correct count for all tags - i.e. 0 if a tag is orphaned.
So I wonder if there's a way to achieve this - obviously without sending n+1 queries to the database. A pure-SQL solution might be ok too, usually it's not too hard to map such a solution to SA somehow.
.filter(Tag.content.any()) removes the results with the incorrect count, but it will do so by removing the rows from the resultset altogether which is not what I want.
Solved it. I needed to use DISTINCT in the COUNTs:
cnt = db.func.count(db.distinct(Content.id))
I use old Django version 1.1 with hack, that support join in extra(). It works, but now is time for changes. Django 1.2 use RawQuerySet so I've rewritten my code for that solution. Problem is, that RawQuery doesn't support filters etc. which I have many in code.
Digging through Google, on CaktusGroup I've found, that I could use query.join().
It would be great, but in code I have:
LEFT OUTER JOIN "core_rating" ON
("core_film"."parent_id" = "core_rating"."parent_id"
AND "core_rating"."user_id" = %i
In query.join() I've written first part "core_film"."parent_id" = "core_rating"."parent_id" but I don't know how to add the second part after AND.
Does there exist any solution for Django, that I could use custom JOINs without rewritting all the filters code (Raw)?
This is our current fragment of code in extra()
top_films = top_films.extra(
select=dict(guess_rating='core_rating.guess_rating_alg1'),
join=['LEFT OUTER JOIN "core_rating" ON ("core_film"."parent_id" = "core_rating"."parent_id" and "core_rating"."user_id" = %i)' % user_id] + extra_join,
where=['core_film.parent_id in (select parent_id from core_film EXCEPT select film_id from filmbasket_basketitem where "wishlist" IS NOT NULL and user_id=%i)' % user_id,
'( ("core_rating"."type"=1 AND "core_rating"."rating" IS NULL) OR "core_rating"."user_id" IS NULL)',
' "core_rating"."last_displayed" IS NULL'],
)
Unfortunately, the answer here is no.
The Django ORM, like most of Django, follows a philosophy that easy things should be easy and hard things should be possible. In this case, you are definitely in the "hard things" area and the "possible" solution is to simply write the raw query. There are definitely situations like this where writing the raw query can be difficult and feels kinda gross, but from the project's perspective situations like this are too rare to justify the cost of adding such functionality.
Try this patch: https://code.djangoproject.com/ticket/7231