Django-postgress: multiple primary keys are not allowed - django

when I am useing django.db.backends.postgresql_psycopg2 and running manage.py syncdb, following error raised
django.db.utils.ProgrammingError: multiple primary keys for table "token_place" are not allowed
LINE 3: "signatureid" integer NOT NULL PRIMARY KEY REFERENCES "s...
model:
class TokenPlace(models.Model):
token = models.ForeignKey(Token, db_column='tokenid', primary_key=True)
signature = models.ForeignKey(Signature, db_column='signatureid', primary_key=True)
place = models.IntegerField(primary_key=True)
class Meta:
db_table = 'token_place'
my models work correctly with mysql but I must deploy it in postgres
how to fix this problem?

After reading your answer I finally get the question, you are looking for composite keys in Django. Unfortunately this is not supported by Django yet. If you need it there are a few options:
Try the Django Composite Key project: https://github.com/simone/django-compositekey
Use the patches and explanation given on this page to add the support to Django: https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys
Use SQLAlchemy (http://www.sqlalchemy.org/) for querying as it does support this properly.
Use a single primary key column in Django and read/write from/to a writable view which communicates with the actual table in the background.

Related

Why is unmanaged model not calculating id in Django?

I have an unmanaged model in Django:
class Person(models.Person):
name = models.CharField(max_length=200)
class Meta:
managed = False
db_table = '"public"."person"'
Somewhere in my tests, I try to create a Person entry in the DB:
person = Person(name="Ariel")
person.save()
But then I get an error:
django.db.utils.IntegrityError: null value in column "id" of relation "person" violates not-null constraint
DETAIL: Failing row contains (null, Ariel).
Outside tests, everything works fine. In the tests, I initialize the DB with the tables referenced by the unmanaged by loading a schema dump.
The Django docs states that "no database table creation, modification, or deletion operations will be performed for this model", and that "all other aspects of model handling are exactly the same as normal", including "adding an automatic primary key field to the model if you don’t declare it". But doesn't that mean this code should work? How come Django and Postgres are not taking care of the id? Am I doing something wrong? How can I fix it?
Surely the issue that you're having is that in your PostgreSQL table, id is not an auto incremental field and it nulls by default.
It's quite a common issue when using unmanaged models on Django. You need to cover every single aspect of the table you're using.

Django CharField unique=True seems not working while unique=True is set

I'm using Django 3.0.2 and sqlite3 DB.
I set following simple models:
from django.db import models
class Description(models.Model):
IDENTIFIER_LENGTH = 30
identifier = models.CharField(max_length=IDENTIFIER_LENGTH, blank=False, unique=True, primary_key=True)
Strangely, the unique=True seems not working. Following code run in shell mode
from testunique.models import Description
object = Description('first-object')
object.save()
object.save()
doesn't raise any error. For the record, here is the SQL code of the migrations:
BEGIN;
--
-- Create model Description
--
CREATE TABLE "testunique_description" ("identifier" varchar(30) NOT NULL PRIMARY KEY);
COMMIT;
What is wrong here? Thanks for the answer.
Django considers records with a set primary key as records already in the database. Therefore it will not perform a INSERT … query, but an UPDATE …. It is sometimes used as a trick to set the primary key in Django to None to make a copy of a given record (since then Django will make another INSERT … query).
You can force insertion with:
Description.objects.create(name='first-object')
Description.objects.create(name='first-object') # raises an error
or you can work with force_insert=True:
Description(name='first-object').save(force_insert=True)
Description(name='first-object').save(force_insert=True) # raises an error

Django 1.9 - IntegrityError on update

class Configuration(models.Model):
configuration_key = models.CharField(max_length=100, unique=True)
configuration_value = models.TextField()
configuration_description = models.TextField("a brief description of this setting", blank=True)
The above is my model. I am able to able to add configurations using the admin. I have not configured any customizations on the admin. It is a very basic
admin.site.register(Configuration)
When I update an existing configuration with admin, it throws an IntegrityError
duplicate key value violates unique constraint "config_configuration_configuration_key_key"
DETAIL: Key (configuration_key)=(SAMPLE_CONFIGURATION) already exists.
My question: Shouldn't the admin know that an existing configuration is modified and handle this accordingly? Am I missing something? To be clear - SAMPLE_CONFIGURATION - there is only one such row in the table with that configuration_key. I am trying to edit the configuration_value for that row using the admin and it throws the Integrityerror.
Your code is just fine, there must be no error. Update Django to the current version and try again.
Also try to isolate the problem. Use tests to reproduce the issue. If tests are passed, then problem not in your code.
Double check what is inside DB, try to update row directly using SQL.
This test updates configuration_value without any integrity issues.
class ConfigurationModelTest(TestCase):
def test_uniq_issue(self):
config = Configuration.objects.create(configuration_key='SAMPLE_CONFIGURATION',
configuration_value='value')
config.save()
config.configuration_value = 'updated_value'
config.save()

Django OneToField reference to default 'id' instead of actual primary key

I have a unmanaged model Client
class Client(models.Model):
client_id = models.IntegerField('ID', primary_key=True)
name = models.CharField()
class meta:
manage = False
I use Client to extend User:
class Account(models.Model):
user = models.OneToOneField(User)
client = models.OneToOneField(Client, to_field='client_id')
I thought Django will create foreign key reference to Client.client_id instead of Client.id even without explicit to_field='client_id' because of the definition of Client model. But sqlmigrate shows:
BEGIN;
CREATE TABLE `pubsite_account` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `deg_client_id` integer NOT NULL UNIQUE, `user_id` integer NOT NULL UNIQUE);
ALTER TABLE `pubsite_account` ADD CONSTRAINT pubsite_account_deg_client_id_73086fddd308cd6f_fk_Clients_id FOREIGN KEY (`deg_client_id`) REFERENCES `Clients` (`id`);
ALTER TABLE `pubsite_account` ADD CONSTRAINT pubsite_account_user_id_33ed558985f73b32_fk_auth_user_id FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`);
COMMIT;
And nothing changes with setting to_field='client_id'. Any thoughts would be appreciated.
Django version: 1.8, 1.7 (Yep, I tried both)
Databse: mysql
I cant try right now but I think db_column is what you are looking for
client = models.OneToOneField(Client, db_column='client_id')
After discuss in #django-dev, it turns out to be a bug.
While a ticket has been opened, a developer MarkusH offers a temporary work around:
change managed = False on the model to =True
once you have new migration files, change the managed option on the model back to False
and in the corresponding migration file add 'managed': False, to the options array in the CreateModel operation.
-------edit---------
From the ticket page, this bug has been fixed. So if you come to here for the same thing, just update Django.

Django Two foreign key

I have two models: UserProfile (extended from user) and Cv. I created another model that have two foreign key that come from theses models.
class cv(models.Model):
user = models.ForeignKey(User, unique=True)
cv_d= models.TextField(max_length=1100)
...
class cvv(models.Model):
user = models.ForeignKey(User)
cv= models.ForeignKey(cv)
date = models.DateTimeField(auto_now=True)
In my view, I am trying to insert value on cvv:
...
obj = cv.objects.get(pk=id,active=True)
add=cvv(user=request.user, cv=obj)
add.save()
But, I am getting the following error:
(1452, 'Cannot add or update a child row: a foreign key constraint fails
How can I insert theses 2 foreign key on my model?
Welcome to one of the many reasons why you shouldn't use MySQL. This happens most often when you have one table that is MyISAM and one table that is InnoDB. Since myISAM doesn't support FK constraints all hell breaks loose when django creates a FK between the tables.
The fix is to either make both tables InnoDB or MyISAM and not to mix them. Or even better drop the bad RDMS for something not MySQL.