Django: Many-to-many through a table with (only) compound key - django

I have a legacy database with a table storing a many-to-many relationship, but without a single primary key column. Is there any way to convince Django to use it anyway?
Schematically:
Product 1<---->* Labeling *<---->1 Label
The Labeling table uses (product_id,label_id) as a compound primary key, and I don't see any way to inform Django about this. (Just using through gives me Unknown column 'labeling.id' in 'field list'.)
Do I need to fall back to custom SQL? Or am I missing something?

hope this helps you,
http://docs.djangoproject.com/en/dev/ref/models/options/#unique-together
http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.Field.db_index

If you add a unique_together to the model for the many-to-many table, Django will use those columns instead of expecting a primary key called id.

Related

How to enforce database constraints between two foreign keys on a join table?

I am trying to enforce a constraint between two foreign keys on a join table, and I don't know whether I can do it using the database, or whether I should do it through my app, or my ORM.
Here are my tables:
Dataset
Tag
- Dataset: FK
- name: string (eg: "park", "church", etc)
Place
- Dataset: FK
- latitude
- longitude
PlaceTag (my join table)
- Tag: FK
- Place: FK
- note: string (eg: "this place is my favorite park")
I want to enforce the constraint that each PlaceTag has a Tag and a Place that belong to the same Dataset. Should I do this using the database, or my app? Or should I re-structure my models to enforce this constraint more easily?
FWIW, this is an open-source project, and my PR for creating these tables is up here: https://github.com/mapseed/api/pull/161/files The project is using Django, if that helps.
One way of "enforcing" (note the quotation marks) this in Django would be to override the PlaceTag's save() method. In there you can raise an exception whenever self.place.dataset != self.tag.dataset. Yet you should note that there are situations in which Django will not call the custom save() method of a model:
When calling the update() method on a queryset. This method is meant for bulk updates and hence, for performance reasons, proceeds with the update directly at a database level (reference).
Inside (data) migrations custom save() methods are not available.
In these two situations the approach I propose will not be useful to enforce the constraint (hence the quotation marks at the beginning). This is of course not the same and not as strong as enforcing this at a database level. Anyway I don't think there is a portable way (i.e. available in any or most SQL database engines) of enforcing such a condition since checking it will require a join on other tables, yet I may be wrong on this one.

Create table without checking foreign key on unexisting table

I'm adapting a really big query (MySQL to SQL) that creates lots of tables and relationships. The problem is that it always check if a table exists prior to adding a foreign key referencing to that table.
So I have to reorder the queries to avoid this problem, and my question is if there's a instruction that can turn that check off, so it'll create the tables and add references without stopping the query with every error it encounters.
I'm working with SQL in an Azure DB.
Thank you.
Easiest way is to create all tables first and then add constraints using ALTER TABLE.
For example:
CREATE TABLE a(id INT PRIMARY KEY IDENTITY(1,1), b_id INT, c CHAR(10));
CREATE TABLE b(id INT PRIMARY KEY IDENTITY(1,1), z INT);
ALTER TABLE a ADD CONSTRAINT FK_a_b_id_b FOREIGN KEY (b_id) REFERENCES b(id);
Rextester Demo

ManyToMany self-referenced with extra column in Doctrine

I have problem which is easy to solve with pure SQL but I need to solve it with Doctrine in YAML.
I have well known db tables users and friends. Where users table has primary key user_id and friends has friend_id and friend_with_id which uses user_id from table user. My problem starts when I need to add there one more column mood. With SQL I add to table friends onemore column named mood and it's done with doctrine I can't find any solution.
For better understanding I add db scheme:
I dont see any self-reference relationship here. Both friend_id and friend_with_id points to users.user_id. What I see is, two one-to-many relationships from the user side OR two many-to-one relationships from the friends side.
So, there will be two ArrayCollection objects (ManyToOne) in the Friend entity corresponding to friend_id and friends_with_id. Similarly two ArrayCollections (OneToMany) on the User entity, namely, myFriends and friendsWith.

Web2py: id as foreign key

I am trying to implement some tables that mimic inheritance in a relational (sqlite) database. My goal is to have one master table with general fields, and some child tables with specialized fields. Every record in the master table will have exactly one counterpart in exactly one of the specific tables. What I want looks like this:
Master table:
id (PK) #Your average web2py unique auto-incrementing int field
#Some general fields
Child tables:
id (PK, FK referencing the PK of the master table)
#Some specialized fields
Having a default "id" PK for each child table has no use to me. All I need is an FK reference to the master table, which can serve as the PK for the child tables. This means that the PK of the child tables will be unique, but will contain gaps. This is because a child table will only reference some of the records of the master table.
I get the impression that doing this (not giving the child tables the regular "id" PK) is against the Web2py way. So my questions are as follows:
Is this a Bad Idea™? If so, why?
How would I implement this? Can Web2py handle tables that don't have an auto-incrementing int as PK?
It's very important for me to apply the correct style and practice when writing code. I am open to alternative approaches.
Thank you for your help.
See the book section on keyed tables. If this is a database specifically for use with web2py, I suggest you stick with the standard web2py approach:
db.define_table('master', ...)
db.define_table('child', Field('master', db.master))

How do I express a Django ManyToMany relationship?

I'm hitting a wall here and I know this is a simple question, but I was unable to find it here.
In an ER diagram, what would the relationship be between two objects that have a ManyToMany relationship, in terms of the intermediary table?
Example:
item ---- item_facts ---- fact
I feel like it should be one to one but I'm not completely sure.
user --many2many-- group
user 1----n user_group n---1 group
In django documentation it states that
A many-to-many relationship. Requires a positional argument: the class to which the model is related. This works exactly the same as it does for ForeignKey, including all the options regarding recursive and lazy relationships.
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the model that contains it. Since some databases don't support table names above a certain length, these table names will be automatically truncated to 64 characters and a uniqueness hash will be used. This means you might see table names like author_books_9cdf4; this is perfectly normal. You can manually provide the name of the join table using the db_table option.
And ForeignKey definition is like:
A many-to-one relationship. Requires a positional argument: the class to which the model is related.
So,ManyToMany relations created by django are creating intermedıary tables that are 1 to N.
Not sure what the question is here. You say that the two objects have a many-to-many relationship.
If two objects (entitied, tables) have a many-to-many relationship, whether you include the intermediate table in the diagram or not, is irrelevant. They still have a many-to-many relationship.