Compound/Composite primary/unique key with Django - database

How can you create models (and thus tables) with a compound (composite) primary/unique key using Django?

Django does not support compound primary keys. You can create a single compound unique key with Meta.unique_together.

if you want only unique mixed fields together use belowcode:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField()
key2 = models.IntegerField()
But if you want unique together and one of column be primary, set primary argument for model column, similar below code:
class MyTable(models.Model):
class Meta:
unique_together = (('key1', 'key2'),)
key1 = models.IntegerField(primary_key=True)
key2 = models.IntegerField()

Related

Django: UUID in automatic ManyToMany fields

I want to use UUIDs for database ids instead of autoincrement integers. I understand that this can be done by overriding the id in the Model class, for example:
from django.db import models
class Publication(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
title = models.CharField(max_length=30)
class Article(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication)
But, there is still a problem. The automatically generated table for the ManyToMany field uses an auto-incremented id, not a UUID.
Of course, this can address this by defining a "through" table as follows:
...
class Article(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
headline = models.CharField(max_length=100)
publications = models.ManyToManyField(Publication, through="ArticlePublication")
class ArticlePublication(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
article = models.ForeignKey(Article, on_delete=models.CASCADE)
publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
But, according to the Django docs, when you use a "through" table: "Unlike normal many-to-many fields, you can’t use add(), create(), or set() to create relationships". Also, not "DRY".
I want to use add, create and set , and I like the "DRY" feature of the ManyToMany field. I also want to use UUIDs as ids.
I looked for a parameter to ManyToMany to pass in the definition of the automatically created "id" field, but there isn't one.
Am I missing something, or is this a limitation of Django's support for UUID as primary key?

How to enforce uniqueness constraint on a whole column in SQLAlchemy?

I have the following MySQL class.
class MyClassA(db.Model):
b = db.Column(db.String(12))
c = db.Column(db.String(12))
I want to make sure that the values of b are unique over the whole column. How can I change this declaration to enforce that constraint?
Well, you can use the flag "unique=True" like flask sql alchemy's documentation:
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50), **unique=True**)
email = Column(String(120), unique=True)
Flask SQL Alchemy
I hope this helps

Creating new record if the id is not in db

I am working on a cakephp 2.x , I want to create a new row or record if the userid is not present in db otherwise update the record, but the problem is: it is not updating the current record. It is creating the record with the userid "0" I dont know the problem is. If is not finding the record it should create a record with the userid which I am giving.
public function activeNoStatus(){
$this->loadModel('Status');
$userid = $this->request->data('idUser');
$notify = $this->request->data('notify');
$data = array();
$data['activeNo'] = $notify;
$count = $this->Status->findUserId($userid);
if($count>0){
$this->Status->id = $userid;
$this->Status->save($data);
echo "update";
}else{
//create new row
$datanew=array();
$this->Status->id = $userid;
$this->request->data['Status']['activeNo']=$notify;
$this->Status->save($this->request->data);
echo "ok";
}
}
It seems idUser field is not autoincrement, In cakePHP documentaion :
All tables with which CakePHP models interact (with the exception of
join tables), require a singular primary key to uniquely identify each
row. If you wish to model a table which does not have a single-field
primary key, CakePHP’s convention is that a single-field primary key
is added to the table. You have to add a single-field primary key if
you want to use that table’s model.
Rather than using an auto-increment key as the primary key, you may
also use char(36). Cake will then use a unique 36 character uuid
(String::uuid) whenever you save a new record using the Model::save
method.
So you should make idUser autoincrement Primary key.

Django: How to have a multiple foreign keys references the same table in one table

I know that normally Django would create a foreign key called user_id if I simply do something like
from django.db import models
class Order(models.Model):
user = models.ForeignKey(User)
comments = models.CharField(max_length=400)
date_created = models.DateTimeField('created date')
class User(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField()
but what if I need three distinct foreign key in Order that all points to User? The three foreign keys would be user_created, user_modified, and user_status.
The solution is actually straight forward:
class Order(models.Model):
user_status = models.ForeignKey(User, related_name='orders_status')
user_created = models.ForeignKey(User, related_name='orders_created')
user_modified = models.ForeignKey(User, related_name='orders_modified')
You just need to define separate related_names to avoid ambiguity when accessing the Order from the User object.

is it safe to refactor my django models?

My model is similar to this. Is this ok or should I make the common base class abstract? What are the differcenes between this or makeing it abstract and not having an extra table? It seems odd that there is only one primary key now that I have factored stuff out.
class Input(models.Model):
details = models.CharField(max_length=1000)
user = models.ForeignKey(User)
pub_date = models.DateTimeField('date published')
rating = models.IntegerField()
def __unicode__(self):
return self.details
class Case(Input):
title = models.CharField(max_length=200)
views = models.IntegerField()
class Argument(Input):
case = models.ForeignKey(Case)
side = models.BooleanField()
is this ok to factor stuff out intpu Input? I noticed Cases and Arguments share a primary Key.
like this:
CREATE TABLE "cases_input" (
"id" integer NOT NULL PRIMARY KEY,
"details" varchar(1000) NOT NULL,
"user_id" integer NOT NULL REFERENCES "auth_user" ("id"),
"pub_date" datetime NOT NULL,
"rating" integer NOT NULL
)
;
CREATE TABLE "cases_case" (
"input_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "cases_input" ("id"),
"title" varchar(200) NOT NULL,
"views" integer NOT NULL
)
;
CREATE TABLE "cases_argument" (
"input_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "cases_input" ("id"),
"case_id" integer NOT NULL REFERENCES "cases_case" ("input_ptr_id"),
"side" bool NOT NULL
)
From: django web site
Abstract base classes are useful when you want to put some common information into a number of other models. You write your base class and put abstract=True in the Meta class. This model will then not be used to create any database table. Instead, when it is used as a base class for other models, its fields will be added to those of the child class.

Resources