Doctrine ORM, Coalesce in JoinColumn - doctrine-orm

Do we at this moment have a way to use coalesce in the join column for relations?
For example a car has many parts. A car can have a relation to itself. I want to make demo cars, which refer to another car (the original car). But i do not want to copy all the parts of the car. So i would like to join using Coalesce. join part.car_id = coalesce(car.car_id, car.id). So we would use the coalesce to first check if the car as a car_id, referring to the original car, if so, its a demo car and we use the car id of the original car. If not than use the car's own id. For example when calling the original car.
If this would not be possible using the Annotations. Would it be possible in a different way?

It is not possible to define conditions on doctrine association. Association is always defined between concrete entities and fields.
It also doesn't work with constrains in relational databases.
I think you should use different design to achieve it. I would recommend to introduce new entity Model and associate parts to this entity and then have a Car which is also associated to the Model.

Related

Which object should hold the many-to-many relationship in Django?

I'm just learning Django and have a quick question: I see that when creating a model you can define a many-to-many relationship between two objects. While you assign this relationship to one of the objects, Django actually creates a third table to resolve this M:N relationship. Given this, does it matter which object holds the many-to-many field or can it appear on either of the two, related objects? (coming from a relational DB background, I've got to say that the concept of assigning the M:N to one table feels a bit odd - I'm still not over the idea of not starting with an ER diagram)
No, it doesn't matter. It can go on either of the two.

Django, multi-table inheritance is that bad?

This isn't really specific to django.
One can model
Place (with location, name, and other common attributes)
- Restaurant (menu..)
- ConcertHall (hall size..)
in two separate tables and let each one hold all the fields they need. (in django world, this is called abstract inheritance)
in three tables, where one holds the common fields and the other two has their own unique fields. (multi-table inheritance in django)
The authors of book Two scoops of Django 1.8 strongly advise against using multi-table inheritance.
Say you want to query places based on it's location and paginate the results (It doesn't have to be a location, can be any other common attribute we want to filter on)
I can see how I can achieve it using Multi-table inheritance.
select place.id from place LEFT OUTER JOIN "restaurant" on (
restuarant.id=place.id) LEFT OUTER JOIN "concerthall" on (
concerthall.id=place.id) where ... order by distance
Is it feasible to do it with abstract inheritance?
According to Django documentation: Model inheritance:
The only decision you have to make is whether you want the parent models to be models in their own right (with their own database tables), or if the parents are just holders of common information that will only be visible through the child models.
I think both possibilities are just tools, equally good tools and it just depends on your use case for their appropriateness. Surely there are specific things to consider for both approaches, and conceptually sometimes multi-table inheritance may be more difficult to comprehend, but other than that this topic just turns to become opinionated.
If you need a single queryset for both models, then it is logical that you consider multi-table inheritance rather than abstract models, because otherwise you would need to get into combining two querysets into one, most probably by using lists as this relevant answer suggests, but you would definitely lose ORM functionality.
It depends on your usecases, but Django ihave a good Database ORM for Database Normalized table structure.
Keeping the base fields in a model and keeping the specifics on another is the best approach in Database Normalization logic because you may have query on different tables and that is not a desired situation. Django relations and reverse relations offers you what you need at this point.
An Example based on yours considering you are using Multi Table Inheritance:
Place.objects.filter(location=x)
Place.objects.filter(location=x, Q(Q(concerthall__hallsize__gt=y)| Q(restaurant__menu=z)))
Place.objects.filter(location=x, concerthall__id__isnull=True)
First will return you all Restaurants and Concert Halls in x.
Second will return you All places which are Concert Halls with hall sizes greater than y or Restaurants with menu z.
Last one is a super magic query that will return you all places in location x which is not a Concert Hall. That is useful when you have many Models inheriting from Place. You can use <model_name>__id for including/excluding tables according to your needs.
You can built great JOINS including many tables and do stick to Database Normalization rules while doing this. You will keep your related data in one place and avoid possible data integrity problems.

How to parameterize django aggregation?

I want to do something like
query.annotate(Count('foreign_model_relation', somefield_from_foreign_model=some_value))
That means, i want to count, how many objects from another queryset are pointing to this object. The difference between using something like filter(in=other_queryset) is, that i would like to combine this in one query, to avoid generating one query per object.
Simplified Models:
Group
Object
group (Group)
Vote
object (Object)
up (Boolean)
Now i want to query the up/down count of all Objects for one Group, with one or two queries, not with one/two queries per Object.
You can do this with two queries:
YourObject.objects.filter(vote__up=True, group=some_group).annotate(total_votes_up=Count('vote'))
YourObject.objects.filter(vote__up=False, group=some_group).annotate(total_votes_down=Count('vote'))
But I think that should exist some more elegante way to do this.

Creating OneToOneField with base model

Sometimes in course of time model becomes too huge. There is a desire to split it on a several models and connect them with OneToOneField. Fields that uses most often, kept in primary model, other fields moves into other models.
However this approach becomes a headache when creating new instance of model. When you can initialize one model with one line:
MyModel.objects.create(foo=1, bar=2)
you needs at least two lines to initialize two models:
instance = MyModel.objects.create(foo=1, bar=2)
MyRelatedModel.objects.create(mymodel=instance, hello=3, world=4)
Is there a way to simply create two models in one line, or i should write my own auxiliary function for such problems?
I think, You should not split your models with onetooneField because of following reasons
As you said there will be some extra code to manage them.
Every time you query them you will have to make two queries instead of two.
Please don't forget that django models has two functions. The keep data related methods and they keep data model of your application. Some bussiness models have tables that have hundreds of fields. This is completely normal. If you really want to split them. you might want to check out abstract base classes. those are base classes for your model that does not have a seperate tables for themselves https://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
But if you insist on going with oneToOne field you can wrap object creation code in one of the model's method like
MyMode.create(attr_for_model_A=1, attr_for_model_B=2)
Or you can overwrite default manager's create method to create two method instead of one
https://docs.djangoproject.com/en/dev/topics/db/managers/#modifying-initial-manager-querysets
In my opinion, non-of those will worth having small model code.

Subsonic 3 and table relationships

I have something like this:
Order order = new Order();
Item item = new Item();
order.Items.Add(item);
order.Save();
How can I do this with Subsonic? The method that refere to a related table is IQueryable.
You have three options:
Set the foreign key in Item to the id of your Order object and save both.
Create a partial class which has a method "AddItem", encapsulating this functionality
Modify the T4 templates to allow you to do this automatically; unfortunately this feature doesn't come out of the box yet.
The advantage with Subsonic is that it is flexible, however you occasionally have to fill some of the gaps yourself.
If you are programming something like a shopping cart you can abstract that out into it's own class that can handle marrying the objects together. I personally think it works better than modify the generated objects.