Flask-SQLAlchemy– Can you make a query within a model? - sqlalchemy

I'm building a flask webapp which uses Flask-SQLAlchemy, and I'm also considering using Flask-Login to take care of sessions and to protect certain views.
Flask-Login requires certain methods which I see as useful for various parts of the app (specifically, is_authenticated() and is_active(). However, in all of the examples I've seen these methods just return something fixed. What if I want to make a query on the database. For example, if I want to check if that user actually has an entry in the table (I'm using LDAP to log in, so want users to be able to log in even if they haven't got an entry in the table, although I need to see if they are there).
But I don't know if it's possible to make a query on the table itself from within the class which defines it? Or should I place these functions elsewhere (even though the methods are needed by flask-login within the user class)?

You can. Usually the Session.object_session is a good way to get a session and perform a query:
class MyModel(Base):
__tablename__ = u'model_table'
id = Column(Integer, primary_key=True)
# ...
def my_method(self):
session = Session.object_session(self)
qry = session.query(...).filter(...)
# ...

Flask-Login requires that you provide a user object in the user loader callback. This user does not need to be backed by a database entry, it can be any object as long as it implements the required methods such as is_authenticated() and is_active().
From your description it seems to me that the representation of a user that you need is not one that maps one to one to the user table in your database, since you have valid users that are not in your database.
One approach that you can take is to have two user classes, both implementing the required methods. Let's call these DBUser and LDAPUser. As long as you figure out a strategy to have unique IDs across instances of the two classes Flask-Login will not care.
The DBUser class can be a proper database model based on Flask-SQLAlchemy, with straightforward implementations of the is_xxx() methods. The LDAPUser class, on the other side, can implement these methods issuing any necessary database queries into DBUser.query.

Related

Django/SQL - Creating a table view that joins a table with an override table

So I have the following model structure in my Django App:-
class SuperModel(models.Model):
f1 = models.CharField()
f2 = models.CharField()
class Model(SuperModel):
f3 = models.CharField()
class OverrideModel(models.Model):
fpk = models.OneToOneField(Model, primary_key=True)
f1 = models.CharField()
f2 = models.CharField()
Basically, in my application, the fields f1 and f2 in the Model table contain user information that I have entered. The user has the ability to override this information and any changes he/she makes in the data is stored in the OverrideModel table (because I do not want to lose the information that I had entered first). Think of it as me creating user profiles earlier while now I want the user to be able to edit his/her own profile without losing the information that I had entered about them.
Now, since the rest of my application (views/templates etal) work with the field names in the Model class, what I want is to create a view of the data that fetches the field f1 from the override table if it exists, otherwise it should pickup f1 from the table it used to earlier without resorting to a raw queryset.
I will describe everything I have considered so far so that some of the other constraints I am working with become clear:-
Model.objects.annotate(f1=Case(When(overridemodel__f1__isnull=True, then=F('f1')), default=F('overridemodel__f1'))).
This throws the error that the annotate alias conflicts with a field already in the table.
Model.objects.defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...).
This approach cannot be applied because I could not figure out a way to apply an outer join using extra. The override model may not have a row corresponding to each model row. Specifying the override table in the tables clause performs a cross product operation which combined with where can be used to perform an inner join, not an outer join (although I'd be happy to be proved wrong).
EDIT: I have realized that select_related might be able to solve the above problem but if I filter the queryset generated by Model.objects.select_related('overridemodel').defer('f1').extra(select={'f1': 'CASE WHEN ... END'}, tables=..., where=...) on the field f1, say qs.filter(f1='Random stuff') the where clause for the filter query uses the Model.f1 field rather than the f1 field generated in extra. So this approach is also futile.
Using Model.objects.raw() to get a raw queryset.
This is a non-starter because the Django ORM becomes useless after using raw and I need to be able to filter / sort the model objects as part of the application.
Defining methods/properties on the Model class.
Again, I will not be able to use the same field names here which involves hunting through code for all usages and making changes.
Creating a view in the database that gives me what I want and creating an unmanaged model that reads the data from that view.
This is probably the best solution for my problem but having never used an unmanaged model before, I'm not sure how to go about it or what pitfalls I might encounter. One problem that I can think of off the top of my head is that my view always has to be kept in sync with the models but that seems a small price to pay compared to hunting through the codebase and making changes and then testing to see if anything broke.
So, there you have it. As always, any help / pointers will be greatly appreciated. I have tried to provide as minimal an example as possible; so if any more information is required I'll be happy to provide it.
Also, I am using Django 1.8 with MySQL.
I realized that there is no easy canonical way to solve my problem. Even with using option 5 (creating a view that is ORM manipulated using an unmanaged Model), I would lose the related query names on the original model that are being used in my filtering / sorting.
So, for anyone else with a similar problem I would recommend the approach I finally went with which is not keeping an OverrideModel but an OverriddenModel which keeps the values that are overridden whenever the user makes changes and updating the original Model with the override values so that the model always contains the values on which filtering / querying is going to occur

Separate get request and database hit for each post to get like status

So I am trying to make a social network on Django. Like any other social network users get the option to like a post, and each of these likes are stored in a model that is different from the model used for posts that show up in the news feed. Now I have tried two choices to get the like status on the go.
1.Least database hits:
Make one sql query and get the like entry for every post id if they exist.Now I use a custom django template tag to see if the like entry for the current post exist in the Queryset by searching an array that contains like statuses of all posts.
This way I use the database to get all values and search for a particular value from the list using python.
2.Separate Database Query for each query:
Here i use the same custom template tag but rather that searching through a Queryset I use the mysql database for most of the heavy lifting.
I use model.objects.get() for each entry.
Which is a more efficient algorithm. Also I was planning on getting another database server, can this change the choice if network latency is only around 0.1 ms.
Is there anyway that I can get these like statuses on the go as boolean values along with all the posts in a single db query.
An example query for the first method can be like
Let post_list be the post QuerySet
models.likes.objects.filter(user=current_user,post__in = post_list)
This is not a direct answer to your question, but I hope it is useful nonetheless.
and each of these likes are stored in a model that is different from the model used for news feed
I think you have a design issue here. It is better if you create a model that describes a post, and then add a field users_that_liked_it as a many-to-many relationship to your user model. Then, you can do something like post.users_that_liked_it and get a query set of all users that liked your page.
In my eyes you should also avoid putting logic in templates as much as possible. They are simply not made for it. Logic belongs into the model class, or, if it is dependent on the page visited, in the view. (As a rule of thumb).
Lastly, if performance is your main worry, you probably shouldn't be using Django anyway. It is just not that fast. What Django gives you is the ability to write clean, concise code. This is much more important for a new project than performance. Ask yourself: How many (personal) projects fail because their performance is bad? And how many fail because the creator gets caught in messy code?
Here is my advice: Favor clarity over performance. Especially in a young project.

can a PORO access the database?

as my first Rails app, I am building a homework management app which has these tables:
users (from Devise authentication)
schools
courses
assignments
Unlike most examples of course/grading apps I've found, this one is never concerned with all the grades for all students for a particular course, but has only a 1:many relationship between student and courses. So the examples don't really help me.
In order to calculate a user's current grade in any given course (which requires access to data in both course model and assignment model), I am following a suggestion from here on Stack Overflow and creating a PORO in the app/models directory called GradeCalculator.
But this is my first experience with building a PORO into a Rails app, and most of the documentation I'm finding online is for more sophisticated users. I'm assuming it doesn't need a controller (please correct me if I'm wrong), and I see that building it is as simple as:
app/models/gradecalculator.rb
Class GradeCalculator
def calculate_current_course_grade(course_id)
#graded_course_assignments = Assignment.where(user_id: current_user.id, course_id: course_id, graded: true)
#grab weights for each type of assignment in #graded_course_assignments from courses table
#do some calculations
#return the array
end
def calculate_user_GPA(current_user.id)
#more of the same
end
end
My questions are:
Can a PORO access the database (to get data from the courses and assignments tables). Or do I need to pass it all the relevant data from my other classes (like assignments) as params when calling it?
1a. If a simple class can access the database, does the syntax differ from that in the models? Would the above code be able to access Assignment.where?
1b. How would I call this PORO? For example, how would I call it from my views/assignments/index.html.erb?
Can it access Devise's current_user helper?
Tangentially, I just realized that I could store assignment weights in the assigments table. I was thinking chronologically (user inputs number of homework assignments, quizes, etc. at the time of inputting a new course, which determines the weight for each type of assignment), but I could programmatically have each new assignment populate its own weight field by referencing the number of like assignments from its parent course. This would mean, logically, I could do the grade calculation right in the Assignment model. But if extra credit or other changes were added to the course, all the assignments might then have to recalculate their weights. Which way is more correct?
Writing these questions makes me suspect that I am just to pass my PORO the relevant data from my view, let it do calculations on that data and return a grade. But I will post anyway, just in case I'm wrong.
The reason for breaking business logic out into POROs like this is usually to make your code easier to reason about and easier (and faster) to test. To that end, you do not want GradeCalculator to know or care how Assignment works. You should just pass GradeCalculator all of the data it needs (or a Relation, which quacks like an Enumerable). Having GradeCalculator call Assignment.where means that your tests will depend on ActiveRecord, and the database, which means they'll be slow. If GradeCalculator just expects an array, in your tests you'll just have to mock an array of objects that respond to whatever attribute methods GradeCalculator needs to know about, and you'll be able to run them without loading Rails at all. (It's common to have a separate spec_helper.rb and rails_helper.rb so that specs that don't need Rails can run without loading Rails, which makes them so much faster.)
Per your second question my advice is similar: Decouple your POROs as much as possible from Rails and from Devise.

which solution is good practice hibernate save data in database?

I have two entities which are Student and Class entities.
Student and Class are many to one relationship. So student contains class attribute.
Now i want to save or create a student associate with existing class(means i know primary key ID already).
Solution 1:
Student student = new Student();
Class class = session.load(classId);
student.setClass(class);
session.save(student);
Solution 2:
Student student = new Student();
Class class = new Class();
class.setClassId(classId);
student.setClass(class);
session.save(student);
My question here is in solution 1 it will issue two SQL, one is to get Class another is to insert student. But in solution 2 only need to have one SQL. If I have more class attribute,
i will load and issue more select sql before insert. It seems not that efficient. Is there any side-effect in solution 2?
which way to do save/insert is better? By the way, i do not set up cascade.
Thank you
Yee Chen
Solution 1 won't issue an SQL query to load Class. Unlike get(), load() returns a proxy object with the specified identifier and doesn't perform a database query immediately. Thus, load() method is a natural choice for this scenario (when you actually need to load an object, use get()).
Possible side effect of solution 2 depends on cascading configuration of relationship and so on. Even if it works fine in your current case, it makes your code more fragile, since seemingly unrelated changes in the code may break it.
So, I recommend you to use Solution 1 and don't worry about performance.
Is there any side-effect in solution 2?
First of all, you haven't associated your student with any class there.
Secondly, where do you get that class id from in the general case? At some earlier point in time, you had to either fetch an existing class instance from the DB, or create a new instance and persist it, so that you get its id. Of course, reusing an entity you already have is fine, but juggling with ids like you do above is IMHO not.
Thirdly, it is not a good idea to prematurely optimize your app. Get it to work properly first, then measure performance, and optimize only if and where needed.

Design pattern for a class that works on a collection of other objects?

I have a User model that can hold 1-n UserGroup models, each of which holds data about the user's relationship with a specific group (for example, if they're the admin of the group, when they joined the group, etc.).
I'd like to provide some helper methods like isGroupUser() and isGroupAdmin() that work on the entire set of UserGroup models stored in a User model. Right now these methods are in the User model, but they just about double the size of the model.
Does it make sense to push the code that works on the UserGroup models into its own class? So then the User model would contain a single instance of this "interface" class, which would also now contain the UserGroup models to work on. I feel like this keeps related code nicely separated and the User model from becoming overwhelming.
Also, is there a design pattern for this sort of thing? It seems like a class that works on a collection of other objects would be pretty common.
Thanks for your insight!
Iterator: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation. [GoF, p257]
Visitor: Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates. [GoF, p331]
If you are new to design patterns a quick overview is available at http://www.vincehuston.org/dp/
I suppose the other big benefit of doing it that way pushes all of this UserAccessControl or UserPermissions into a nice reusable setting or object.