Web2py: id as foreign key - foreign-keys

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))

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.

Structure for Categories, subcategories and Products

I have a table "Category" and another "Subcategory". Then I have "Products" table.
Some of these products will be related directly to the "Subcategroy" table, but some of them will be related directly to "Category". What should be the tables structure in this case?
Use Association Mapping
This chapter explains mapping associations between objects.
Instead of working with foreign keys in your code, you will always work with references to objects instead and Doctrine will convert those references to foreign keys internally.
http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html

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.

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.

Doctrine2: Uni-directional #OneToMany with foreign key?

I have a "Product" entity with many "Video" entities, and I only need a unidirectional #OneToMany with foreign key (one product, many videos). My Product-side "key" is not primary or unique, which is why I need it to be unidirectional (eg, "select * from videos where product_family = 2143")
I'm using Doctrine 2.1
Is there yet a way to do uni-directional #OneToMany with only a foreign-key in Doctrine 2.1? If not, soon?
UPDATE: I found a relevant quote from Roman Borschel on May 2010:
"this would need quite some special-case handling in many places. In the light that there are 2 reasonably good alternatives (mapping through a jointable or simply making the association bidirectional) we do not consider this something that really needs to be done."
Has this opinion by the Doctrine2 team changed?
OneToMany by design has the related ID on the "Many" side of the relationship. So to make the child table relate to the parent without an additional field in a join table is not possible.