Model linking to other models based on field values - django

I'm working on simple ratings and comments apps to add to my project and am looking for advice on creating the models.
Normally, I'd create these database schemas like this:
comment_
id - primary key
type - varchar (buyer_item, buyer_vendor, vendor_buyer)
source_id - int (primary key of the table based on the type)
target_id - int (primary key of the table based on the type))
timestamp - timestamp
subject - varchar
comment - text
rating_
id - primary key
type - varchar (buyer_item, buyer_vendor, vendor_buyer)
source_id - int (primary key of the table based on the type)
target_id - int (primary key of the table based on the type)
timestamp - timestamp
rating - int (the score given, ie: 1-5 stars)
This would let me have simple methods that would allow me to apply comments or ratings to any type of thing by setting the proper type and setting the id's of who submitted it (source_id) what it applies to (target_id), like:
add_comment('user_product', user.pk, product.pk, now, subject, comment)
add_comment('user_vendor', user.pk, vendor.pk, now, subject, comment)
I know in the models you define the relationships to other tables as part of the model. How would I define the relationship in these types of tables where the TYPE field determines what table the SOURCE_ID and TARGET_ID link to.
Or should I omit the relationships from the model and set the joins up when I get the QuerySets?
Or just trash the who common table idea and make a whole bunch of different tables to be used for each relationship (eg: user_ratings, product_ratings, transaction_ratings, etc)?
What's the best practice here? My DBA senses say use common tables, but Django newbie me isn't sure what the natives do.
Thanks!

I think what you are looking for is a Generic Relation, and you can find this type of thing in the contenttypes framework: https://docs.djangoproject.com/en/1.0/ref/contrib/contenttypes/#generic-relations

Related

DynamoDB LSI or GSI to query on composite attribute

I'm trying to use DynamoDB for my JAVA project and I have this (from my point of view) strange scenario that I have to cover. Let me to explain how I organize my table:
Suppose that I have to store these info related to Books:
book_id (UUID) used as PK autogerated
author_id (UUID)
type (String)
book_code (UUID) this different as concept from book_id
publishing_house_id (String)
book_gender (String)
And additional dynamic attributes that are not queryable and I'm thinking to store as Document (JSON)
Now, the queries that I need are:
Insert/Get/Update/Delete book by book_id
Get all book by author_id
Get all book by author_id and type
Get book by book_code, publishing_house_id, book_gender (I would like to highlight that this tuple will be unique)
Using the book_id as PK I'll be able to cover the first query set (CRUD using the book id)
For the query #2 and #3 the idea is to create a GS index where the author_id is the PK and type is the SK.
In order to cover the query #4 I'm thinking to:
Create an dedicated Attribute book_sk where I'll store:
book_gender#publishing_house_id#book_code
Create a Local Secondary Index using this book_sk as SK
Probably I can move book_code, publishing_house_id, book_gender into a Document field instead to have these unquerable attributes here.
I'm not very sure about this design.
What do you think?
In that case, is it better to use a LSI or GSI for the query #4?
For #4, if you're always getting a book by those three together, then make an attribute with that concatenated value and use it as the PK of a GSI, making it easy to directly look up.

Define unique columns on ManyToMany in Doctrine

I'm trying to add unique columns on a pivot table created via a ManyToMany association.
I found this page of the documentation explaining how to generate a database unique constraint on some columns with this example:
/**
* #Entity
* #Table(name="ecommerce_products",uniqueConstraints={#UniqueConstraint(name="search_idx", columns={"name", "email"})})
*/
class ECommerceProduct
{
}
But this only works if I create the pivot table via a third entity and, in my case, I created the pivot table using a ManyToMany relation (in the same fashion as this code).
Is there a way to add unique columns on pivot table while still using ManyToMany or do I need to rely on a third entity?
While #Table annotation proposes a uniqueConstraints option, #JoinTable does not. Thus, if you want to add a unique constraint on your association table, you will have to actually create another entity explicitly.
That being said, the default join table should not need anything more than the default configuration set up by Doctrine. Currently, when adding a ManyToMany association, the join table is composed of two fields and a composite primary key relying on both fields is created.
If your association table only contains the two basic fields referring to both sides of your association (which is necessarily the case if you use #ManyToMany), the composite primary key should be all you need.
Here is the generated SQL for the basic example where a User has a ManyToMany association with Group (from this section of the documentation):
CREATE TABLE users_groups (
user_id INT NOT NULL,
group_id INT NOT NULL,
PRIMARY KEY(user_id, group_id)
) ENGINE = InnoDB;
ALTER TABLE users_groups ADD FOREIGN KEY (user_id) REFERENCES User(id);
ALTER TABLE users_groups ADD FOREIGN KEY (group_id) REFERENCES Group(id);
As you can see, everything is properly set up with a composite primary key which will ensure that there can't be duplicate entries for the couple (user_id, group_id).
Of course there is another alternative, Alan!
If you need a Zero to Zero relationship, the only alternative is defining the unique constraint per each pk in the agregated table, to make doctrine figuring out about zero to zero relationship.
The problem is that Doctrine's people hadn't considered zero to zero relationships, so the only alternative for this is manytomany relationship with one unique constraint per pk.
If you have doubts about final-state of your doctrine implementation of your E-R model, I strongly recommend mysql-workbench-schema-exporter. With this php tool, you can easily export your mysql workbench E-R schema to a Doctrine's working classes schema, so you would be able to easily explore all your alternatives ;-)
Hope this helps

Which is better? city.state.id or city.state_id

I have to table with relation.
State
id
name
City
id
name
state
Which is better in performance?
city.state.id or city.state_id
city.state_id is better anyway. city.state will do another fetch from database.You can avoid this using select_related.If you need only id of foriegn key, no need of select_related here.Just do city.state_id(since foriegn key id will fetch in the query which gives city object).
city.state_id is better than city.state.id. Because It makes only a query instead of two.
BTW, You can use Django Debug Toolbar for debugging queries.
the <field>_id field you see is the database column name
docs
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column
So this means it doesn't need to make a separate query to retrieve the foreign key instance (See Select a single field from a foreign key for more details).
But this assumes you haven't used select_related or prefetch_related

Add a Relation foreign key in AX2012

I have to create 2 new tables: EmployerTypeTable and ListDocTable
------------------- ------------------
-EmployerTypeTable- - ListDocTable -
------------------_1______________________________*__------------------
- - - -
- - - -
------------------- ------------------
An object of EmployerTypeTable can have many objects of ListDocTable (one to many)
How can I implement this in AX2012?
How to: Create Tables
How to: Add a Relation to a Table
The initial steps for adding a relation are the same regardless of the relation type that you are adding. The later steps diverge based on the relation type.
Remember to save your changes in the AOT.
In the AOT, move to Data Dictionary > Tables, and then expand the table that the relation will be added to.
Right-click the Relations node, and then select New Relation.
Right-click the newly added relation, and then select Properties.
Set the name of the new relationship by modifying the Name property.
In the Table property, select the related table.
Use the Validate property to determine whether the relation should be used to validate data when information is entered into forms.
Right-click the new relation, select New, and then click one of the following:
Normal to specify relation fields without conditions.
Field fixed to specify relation fields to restrict the records in the primary table.
Related field fixed to specify relation fields that restrict the records in the related table.
ForeignKey to specify a correspondence between a foreign key field in the present table to the primary key field in another parent table.
Proceed to the subsection that corresponds to the relation type that you selected in the earlier step.

Creating 'taggable' relationships

Say I have two tables that can have 'tags' associated with them. With potentially more in the future.
tracks -
id, title, artist, etc...
artists -
id, name, description, etc...
I want to be able to have a general table called 'tags'
tags -
id, title, description
How would I construct the joining table to create the relationship? Is it possible to have it such that foreign keys are applicable to both artists and tracks table?
I was thinking of a structure similar to:
tag_relations -
tag_id (foreign key to tags.id), item_id (either artists.id or tracks.id)
Is this a bad design not having any foreign key integrity on the item_id?
Laravel supports polymorphic relationships which I believe suit the purpose that I require. You can read up about them here.
http://four.laravel.com/docs/eloquent#polymorphic-relations