Let's imagine I have three classes: User,Post, Comment. Standard actions — user can create posts and write comments to these posts. So we have the situation depicted below:
I need to perform these three queries very quickly:
Get all comments for a post
Get all comments for a user
Get post for a comment
And it looks like it isn't possible even if I will use partitioning. At least not with a single reliable dictionary. Probably I need several dictionaries for different queries. Am I correct?
I'm working on the same thing! First of all: My schema is a bit different. I have a user, a topic and a comment. The topic is just a class with a list of comment ids(IEnumerable long), nothing more. The first comment is the post.
Oh, really first of all, little warning: I'm just beginning with Service Fabric, so I might be doing it wrong ;)
The user is not relevant for me. I just store the userid on the comment. When retrieving a list of comments I get the users from the stateful users service. Or I will store the users name in the comment directly, not sure yet.
So that leaves me with topics and comments. First I thought 'lets create a Stateful TopicService and a Stateful CommentService'. But then I realised that for every topic I load I need to call the CommentService for each comment to get the comments.
So I created a TopicService which handles 2 IReliableDictionaries: topics and comments.
Whenever a comment is posted I use the TopicId as the partitionkey and in that partition the comment is stored. So NOT using the commentid !! This way all the comments for a specific topic are in the same partition.
When loading a topic with all the comments I use the TopicId as the partitionkey again, get the topic from the reliabledictionary for the topics and loop the list of comment ids in the reliabledictionary for the comments. Not sure if it helps, but my GetComments looks like this:
var topics = await this.StateManager.GetOrAddAsync<IReliableDictionary<long, TopicModel>>("topics");
var comments = await this.StateManager.GetOrAddAsync<IReliableDictionary<long, CommentModel>>("comments");
List<CommentModel> result = new List<CommentModel>();
using (var tx = this.StateManager.CreateTransaction())
{
ConditionalValue<TopicModel> topic = await topics.TryGetValueAsync(tx, topicid);
if(topic.HasValue)
{
foreach(long commentid in topic.Value.CommentsInternal)
{
ConditionalValue<CommentModel> comment = await comments.TryGetValueAsync(tx, commentid);
if (comment.HasValue)
result.Add(comment.Value);
}
}
await tx.CommitAsync();
}
return result;
I'm not done yet, the method some more work.
Perhaps this helps you :)
edit: ow, there is a disadvantage! When you want to load a single comment by its id, you need to provide the topicid. So my CommentModel class has a CommentId and a TopicId property.
Related
I am learning Django and still a beginner. For practising, i am trying to make a demo social media website. In my project, users can create groups, then they can post and comment there. In the home page, i am trying to add a section like 'recent activities' where a user can see recent activities in that website like "John created a group 'Javascript', Tim posted a comment in 'Python', Sarah posted in 'CSS'" Now i have made some queries like:
groups = Group.objects.all().order_by('-created')[0:5]
posts = Post.objects.all().order_by('-created')[0:5]
comments = Comment.objects.all().order_by('-created')[0:5]
I want to mix them all in a single queryset. Then order them all by the time they were created. I know it's a silly question and i have been stuck here since morning. Can you help me and show me the process please?
You can chain these together and order by the created field with:
from operator import attrgetter
groups = Group.objects.order_by('-created')[:5]
posts = Post.objects.order_by('-created')[:5]
comments = Comment.objects.order_by('-created')[:5]
all_items = sorted(
[*groups, *posts, *comments],
key=attrgetter('created'),
reversed=True
)
Now all_items is a hetrogenous list with different types of objects. This will thus make the rendering process a bit more complicated since a comment probably has different fields than a Post for example.
You can also use chain function from itertools module to combine the querysets and then sort them in reverse order using the created field as key.
from itertools import chain
groups = Group.objects.all()[0:5]
posts = Post.objects.all()[0:5]
comments = Comment.objects.all()[0:5]
queryset = sorted(
chain(groups, posts, comments),
key=lambda instance: instance.created,
reverse=True
)
Long time reader, first time poster, please be gentle.
I've been working on a web app using Flask and SQLAlchemy that allows users to review and comment on MMA fights. I have a list of fights in a SQL table appropriately named "fights" and I'm trying to use dynamic routing to filter through the data. I have a list of all the fights on one route like so:
#app.route('/ufc251')
#login_required
def ufc251():
return render_template('ufc251.html', fights=Fight.query.all())
which helped me make a slick page with all the fights listed, and then made another route for info on individual fights like so:
#app.route('/fight/<int:id>')
#login_required
def fight(id):
id = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html')
so far, so good. If I click on a fight from the main page i get sent to a url fightsite/fights/<fight_id>, which is perfect. The problem that I'm having is that I can't for the life of me figure out how to call the data from the row for a single fight. If i change my route to:
#app.route('/fight/<int:id>')
#login_required
def fight(id):
id = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html', fight=Fight.query.filter_by(id=id).first())
I get the error
sqlalchemy.exc.ArgumentError: Object <Fight 1> is not legal as a SQL literal value
but if i give id a value (i.e. id=1) it will display the data from the first row in my fights table, so i feel like the problem is in the (id=id) part, but after hours of scouring the internet, I can't seem to find a solution.
Any help would be greatly appreciated. And yes, I've read the other StackOverflow article on this subject, however the answer doesn't seem to apply to this situation.
Thank you in advance!
I figured it out, however I decided I'd leave the question in case anybody else has this issue.
i changed:
#app.route('/fight/<int:id>')
#login_required
def fight(id):
id = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html', fight=Fight.query.filter_by(id=id).first())
to:
#app.route('/fight/<int:id>')
#login_required
def fight(id):
id = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html', fight=Fight.query.filter_by(id=id.id).first())
because initially it was passing the argument 'fight_1' instead of just '1'. I hope nobody else has to spend this long trying to solve the same problem!
The use of id to hold a Fight confuses things. Then there's the double query when one would suffice.
Consider changing
id = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html', fight=Fight.query.filter_by(id=id).first())
to
fight = Fight.query.filter_by(id=id).first_or_404()
return render_template('fight.html', fight=fight)
I'm trying to create some social dashboard and therefore I want to retrieve my posts from my page. When I use this one to fetch my posts, it doesn't return me all the information I need (e.g 'picture', 'full_picture', 'attachments')
$user_posts = $facebook->api('/me/posts', 'GET');
print_r($user_posts);
But when I try next one, it still doesn't return me my required information:
$user_posts = $facebook->api('/me/posts?{created_time,id,message,full_picture,picture,attachments{url,subattachments},likes{name},comments{from,message,comment_count,user_likes,likes{name}}}', 'GET');
print_r($user_posts);
Anyone ideas??
I know that this has been asked a long time ago, but maybe useful for someone:
After - me/posts? - you need to make sure to put fields= and then a list of fields required.
So this would be:
$user_posts = $facebook->api('/me/posts?fields={created_time,id,message,full_picture,picture,attachments{url,subattachments},likes{name},comments{from,message,comment_count,user_likes,likes{name}}}', 'GET');
print_r($user_posts);
how to make such query in django.
I have Site model where I can find relation to the topic model. In topic model I can fing relation to the post model. I want to extract post from a site having information only about site, not a topic. What is more posts have to starts with query.
query = request.GET.get('query','')
iweb_obj = IWeb.objects.get(id=iweb_id)
topics = Topic.objects.filter(iweb=iweb_obj)
iweb_posts = []
for t in topics:
posts = Post.objects.filter(topic=t)
for p in posts:
iweb_posts.append(p)
iweb_posts = iweb_.filter(content__istartswith=query)
I have an error that iweb_posts isnt query set and I cant make such action. It is quite obvious, however I do not have idea how to make it works ? I've heard that I can use filter(**kwargs) but I do not know how to use it ?
Your logic looks a little funky since you're overwriting posts each time in the topic loop. You can accomplish what you need without loops and lists using only query set filters (I've added an __in filter, for example):
query = request.GET.get('query','')
iweb_obj = IWeb.objects.get(id=iweb_id)
topics = Topic.objects.filter(iweb=iweb_obj)
iweb_posts = Post.objects.filter(topic__in=topics).filter(content__istartswith=query)
I don't know if i was describing things the right way in the headline, so i will try to do it better here,
Lets say that i am building a forum system and that i have a Post model that has, among other fields, a Foreign key to the Thread model and a foreign key to self so with the name of parent_post, so people will be able to post replies to other posts or start new posts for each thread.
Every thing is working great. The thing i don't know and can't find is how to show the posts in order when i want to show all posts for a thread....
For example:
Thread x:
post a .....
response to post a .....
response number 2 to post a .....
post b ....
post c ....
response to post c .....
response 2 to post c .....
And so on......
I know how to do it in pure SQL and i also know there i can return all thread posts and set them up in order with JS but there must be a way to do it the django way :-)
Thank you,
Erez
I guess your model looks like:
class Post(Model):
....
thread = ForeignKey(Thread)
post = ForeignKey('self')
posttime = DateTimeField(auto_now_add=True)
You will get all mother-posts belong to a thread...
mothers = Post.objects.filter(thread=x, post__isnull=True)
post__isnull=True will filter posts that have no referance to self, which means they are posts that starts the topic...
Then Get posts belong to a single topic and order them...
mother-post = mothers[0]
childs = Post.objects.filter(post=mother-post).order_by('posttime')
But probably, ordering by id (which is default) also solves your problem so, you may not need order_by .
UPDATE:
Yes you can do it in one query Such as for the post with id=12323,
Posts.objects.filter(Q(pk=12323) | Q(post__id=12323))
Link for documentation... That will do what you need.
You have to setup ordering = ['id',] or ordering = ['timestamp',] in your Post model.
When you will do request posts = Post.models.filter(thread=x) all post will be order by 'id' or by 'timestamp' fields. And when you will do posts[a].response_set.all() you will got all responses that ordered according your settings in model Meta class.
PS: sorry for my English
why not have a look at http://www.djangopackages.com/grids/g/forums/