TYPO3 Extension Builder Foreign Key - foreign-keys

Why does the TYPO3 Extension Builder don't generate Foreign keys?
I've set some relations between the models, but in SQL Code there are noe FKs only colums for the Value of the key.
Does anyone can help me?

Cite from Kartsen Dambekalns
It is a half-conscious design decision. Just look up the date when
foreign key constraints where introduced in MySQL, and compare to when
TYPO3 was 'born'.
Of course it would be great to add such references, especially since
MySQL can always handle themm, even if the underlying storage engine
doesn't handle them (in case of which they'll just be ignored).
(source)
Nothing changed till now, so you need to create foreign keys yourself after modeling.
Answer to comment:
how did you handle the relations between two tables? for example I've got a table people which relates to the table house with the column housenr
That depends on relation type of course (1:n, n:1, m:n, etc) and Builder supports creating relations in modeling tool perfectly. Keep in mind, that foreign keys are NOT required for keeping relations in TYPO3.
There are some rules described in TCA section of documentation, i.e. in mentioned case you can use select or group (with internal_type) type of field. For many-to-many relation also you'll need to create MM table. If you'll follow these documents, you can be sure, that in common backend editing form they will be handled properly.
As mentioned before Extension Builder supports creating different types of relations in its click-click modeling tool and it's worthy to spend some time to play with it to see how relations of different types are handled in TYPO3. It uses the same rules that are used in creating relations also in pre-extbase extensions. What's more Builder adds required methods to the models i.e. for getting, attaching and detaching MM objects of given relation field, therefore it's most important to model all your relations at start. In other case you'll need to write these methods manually (which is boring process)

Related

Django - Comments on multiple object types, which approach?

An application has objects of multiple types (Articles, Songs, Profiles, etc), each having their own table. The desired functionality is to allow users to place comments on these objects. What is the best approach considering:
Lookup latency (retrieving an object and all it's comments)
Data integrity
Maintainability
The options are:
The Django contrib comments framework with signals fired on delete operation, calling a routine to delete comments from the comments table.
The Django contrib comments framework with triggers in the database (a mapping between content type PK's / table names is needed).
Give each object type a table for it's comments, with a foreign key.
Give each object type a table for it's comments, AND use the Django comments framework. Drop the frameworks' comment table and create a view using UNION to retrieve all comments (including ON UPDATE/INSERT/DELETE triggers) from the comment tables, mimicing the behavior of the original comment framework table.
Use django.contrib.comments and django signals. You can always switch to a custom solution in the future, if you need it. Don't do premature optimizations, they are hard to maintain.

Differences between one-to-one and foreign key relationships?

Can someone explain the significance of specifying a relationship in a Django model as one-to-one as opposed to just a foreign key?
Specifically, I'm wondering what advantages you get from specifying a relationship as 1-1, if any.
Thanks so much.
The OneToOneField evolved in Django after 'ForeignKey'. Conceptually a ForeignKey with unique=True constraint is similar to OneToOneField.
So if you want to ensure that every picture has one user and vice-versa use a OneToOneField.
If you want one user to have any number of pictures use a ForeignKey.
The way things are selected are also different. In case of doing OneToOneField, you can do user.picture and get the picture directly. In case of ForeignKey you will do user.picture_set[0] to get the first picture or access all the pictures associated with that user.
MultiTableInheritance implicitly uses OneToOneField internally and you can see where the concept originated from.
The additional constraints of a 1-1 provide a tighter and richer conceptual model but can also provide insight that can allow for more intuitive retrieval. As a many to one represents a parent/collection relationship there is an unclear cost associated with the retrieval of any given collection for a particular entity. Since a 1-1 provides a flat mapping there is also a flat cost of retrieval. This would lead to things like preferring eager fetching when relevant, as the join will be be able to be easily optimized and the resultant data set will be a known size.
They are not the same; think about it:
If you have a one-to-one relationship between a User and a Picture, you are saying that a user can only have one picture (and a picture can only have one user). If you were to have a Picture with foreign key to User, then you are saying that a picture must have exactly one user, but a user may have 0, 1 or many pictures.
Django's Foreign Key is a many to one relationship. Now, the difference between them is the same as the difference between a One-To-One and Many-To-One relationship. For example, if you have User and Profile entities. You would like to add a constraint that each User could have one and only one Profile. Then, using a django's one to one field would create a restriction on the database level so, that you won't be able to relate User to multiple Profiles or vice-versa. Where as using Foreign Key wouldn't provide this constraint.

What do I use instead of ForiegnKey relationship for multi-db relation

I need to provide my users a list of choices from a model which is stored in a separate legacy database. Foreign keys aren't supported in django multi-db setups. The ideal choice would be to use a foreign key, but since thats not possible I need to some up with something else.
So instead I created an IntegerField on the other database and tried using choices to get a list of available options.
class OtherDBTable(models.Model):
client = models.IntegerField(max_length=20, choices=Client.objects.values_list('id','name'))
the problem I'm having is that the choices seem to get populated once but never refreshed. How do I ensure that whenever the client list changes that those newest options area available to pick.
What I was really looking for was a way that I could simulate the behavior of a Foreign key field, at least as far as matching up ID's go.
There wasn't a clear way to do this, since it doesn't seem like you can actually specify an additional field when you instantiate a model (you can with forms, easily)
In any case to deal with the problem, since the database is MySQL based, I ended up creating views from the tables I needed in the other database.
To build on #Yuji's answer - if you do self.fields['field'].choices = whatever in the model's __init__, whatever can be any iterable.
This means you can inherit from iterable, and have that object interface to your legacy database, or you can use a generator function (in case you are unfamiliar, look up the yield keyword).
Citing a Django's manual:
Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever.
Why dont you want just export data from the legacy database and to import it into the new one? This could be done periodically, if the legacy database still in use.

Understanding Django's Intermediary Models

I'm trying to understand the purpose of Django Intermediary Models.
Conceptually, they seem to be equivalent to association classes in UML class diagrams. Is there any fundamental difference between the two that I should be aware of?
In spite of the apparent similarity, I've found several resources explaining the purpose of intermediary models, but none of them made any reference to "association classes", which makes me somewhat suspicious.
You're not likely to find any comparisons with UML diagrams in the Django literature - UML modelling isn't really a big thing in the Python world, in my experience.
But looking at your diagram, I'd agree that the concept does seem very similar. Don't forget that the ORM is just that, a mapping of relational concepts onto objects: in this case, the through table maps the intermediary table that is always created in a many-to-many relationship. The only difference is that you only need to specify it manually if you want to add extra information to that relationship, like the enrollment date in your link. If you don't need the extra fields, you don't need to specify the intermediary model, but the table still exists, containing just the foreign keys to each end of the M2M relationship.
They're used to store additional data about a many-to-many relationship. I'm sure this is blasphemy, but I think the best example is from the Ruby on Rails guides, which uses the association between patients and doctors. A doctor has many patients through appointments; a patient has many doctors through appointments as well; but you can't model this relationship directly, because an appointment also has a date and time.
I think you are right that conceptually, they server a similar purpose to association classes in UML.
This is how many-to-many relation is to be implemented in any relational database, it is a fundamental part of relational database design. So I suggest to learn about database design principles first because knowing how database works is necessary for using ORM properly anyway.
wikipedia on Many-to-many

Expando Model in Django

Is it possible to implement 'expando' model in Django, much like Google App Engine has? I found a django app named django-expando on github but it's still in early phase.
It's possible, but it would be a kludge of epic proportions. GAE uses a different database design known as a column-based database, and the Django ORM is designed to link with relational databases. Since technically everything in GAE is stored in one really big table with no schema (that's why you don't have to syncdb for GAE applications), adding arbitrary fields is easy. With relational databases, where each table stores exactly one kind of data (generally) and has a fixed schema, arbitrary fields aren't so easy.
One possible way you could implement this is to create a new model or table for expando properties that stores a table name, object ID, and a TextField for pickled data, and then have all expando models inherit from a subclass that overrides the __setattr__ and __getattr__ methods that will automatically create a new row in this table. However, there are a few major problems with this:
First off, it's a cheap hack and is contrary to the principles of relational databases.
Second, it is not possible to query these expando fields without even more hacks, and even so it would be ludicrously slow.
My recommendation is to find a way to design your database structure so that you don't need expando models.