This is the error that I get when I try to update the value in the "parent" table that the foreign key is looking at in a related table:
ERROR: update or delete on table "product" violates foreign key constraint "pd_family_product_guid_ada83db3_fk_product_guid" on table "pd_family"
DETAIL: Key (guid)=(902d30b8-26ba-ea11-a812-000d3a5bbb60) is still referenced from table "pd_family".
SQL state: 23503
This is what I have for my models:
class Product(models.Model):
guid = models.UUIDField(primary_key=True)
product = models.CharField(max_length=10)
year = models.IntegerField()
previous_product_name = models.CharField(max_length=10)
class StandardProductFieldsMixin(models.Model):
product_guid = models.ForeignKey('Product', on_delete=models.CASCADE, db_column='product_guid')
class Meta:
abstract = True
class ActiveFieldMixin(models.Model):
active = models.BooleanField()
class Meta:
abstract = True
class Family(StandardProductFieldsMixin, ActiveFieldMixin):
new_code = models.IntegerField(null=True)
code = models.DecimalField(max_digits=20, decimal_places=2)
title = models.CharField(max_length=255)
desc = models.TextField(null=True)
fam_desc = models.TextField(null=True)
When I try to change a value of guid in Product, my expectation is that it would automatically change it in Family as well. I'm trying to change it with something like:
UPDATE product
SET guid = '902D30B8-26BA-EA11-A812-000D3A5BBB6B'
WHERE guid = '902D30B8-26BA-EA11-A812-000D3A5BBB60'
I guess I was under the wrong impression. Do I need to do something additional in the model? Looked at the documentation for something like on_update, but not seeing that either an **options or as a parameter for models.ForeignKey.
From what I gather after reading about it for more than an hour, if I want this kind of functionality I just need to add it Postgres manual, by dropping the constraint and adding it back with ON UPDATE CASCADE.
Apparently I'm under the wrong impression:
https://stackoverflow.com/a/61648910/3123109
Sounds like Django model migrations implement neither ON DELETE nor ON UPDATE database CASCADES options. I guess I'd need to drop into the database and implement them there.
Related
There are many similar questions on Stackoverflow, but none of the answers has helped me.
So, when running migrations, Django throws this error:
django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "catalogues_movieslist"
I have this BlackWhiteCartoon model I am trying to create with the migration:
class BlackWhiteCartoon(BaseMovie, BaseList):
authors = JSONField(default=list, blank=True, null=True)
publisher = CharField(max_length=250, blank=True)
year = PositiveSmallIntegerField(blank=True, null=True)
This model inherits from the BaseList model that has only one field, a foreign key:
class BaseList(Model):
belongs_to_movies_list = ForeignKey(MoviesList, on_delete=CASCADE, null=True)
class Meta:
abstract = True
The referenced MoviesList model is the following:
class MoviesList(Model):
creation_date = DateTimeField(auto_now_add=True)
id = AutoField(primary_key=True)
uid = UUIDField(default=uuid.uuid4, editable=False)
user = ForeignKey(User, on_delete=CASCADE, null=True, blank=True)
Also, the BaseMovie model is the following:
class BaseMovie(BaseObject):
language = CharField(max_length=2, blank=True)
note = CharField(max_length=700, blank=True)
class Meta:
abstract = True
And the BaseObject model:
class BaseObject(Model):
id = BigAutoField(primary_key=True)
uid = UUIDField(default=uuid.uuid4, editable=False, db_index=True)
date_added = DateTimeField(null=True)
class Meta:
abstract = True
So, what I have tried:
Migrating everything together: this throws the above error.
Migrating BlackWhiteCartoon without inheriting BaseList first. This migration applies, but as soon as I add BaseList, it crashes with the same error.
Adding unique=True to the id field of MoviesList (both together with all other migrations and before adding BaseList to BlackWhiteCartoon). It throws the same error.
Adding to_field='id' together with 'unique=True'. The same error.
I have manually cleared the latest migrations from django_migrations in PSQL and removed the BlackWhiteCartoon table (to make sure that nothing prevents from migrating). To no avail either.
I have checked whether there are duplicated id's in the MoviesList table in the database. All id's are unique.
I have checked whether there are null foreign keys referencing to MoviesList in the database. There are none.
Also note that I have many models acting in absolutely the same way as BlackWhiteCartoon: Cartoon, Adventure, Action, etc. They are all functioning normally, yet they had been added several months ago.
Any ideas what I can do more?
I have database with many tables; three of those which are interlinked via primary and foreign keys are "Vendor_Details" , "Channel_Details" and "MSO_Details"
models.py
class Vendor_Details(models.Model):
class Meta:
verbose_name_plural = "Vendor_Details"
vendor_name = models.CharField(primary_key = True,max_length=50)
mso_id = models.CharField(unique = True, max_length=20)
class Channel_Details(models.Model):
class Meta:
verbose_name_plural = "Channel_Details"
channel_id = models.CharField(primary_key = True, max_length=20)
vendor_name = models.ForeignKey(Vendor_Details, on_delete=models.CASCADE)
channel_logo = models.CharField(max_length=50)
channel_name = models.CharField(max_length=50)
class MSO_Details(models.Model):
class Meta:
verbose_name_plural = "MSO_Details"
mso_id = models.ForeignKey(Vendor_Details, on_delete=models.CASCADE)
channel_id = models.ForeignKey(Channel_Details, on_delete=models.CASCADE)
channel_number = models.PositiveIntegerField()
So,
Channel_Details is linked to Vendor_Details with vendor_name and
MSO_Details is linked with Vendor_Details and Channel_Details with mso_id and channel_id respectively.
Now, I am inside Django's Administrator's MSO_Details table and trying to click on edit icon of CHANNEL ID column i get a new window opens with message Channel_ details with ID "CH6" doesn't exist. Perhaps it was deleted? May be this is because channel_id is primary key of reference table and DB will not allow the changes? But then the message should had been something different. How can i handle this situation? I clicked on edit for CH_006 and message shows CH6. I am confused whats going on here, what is django's DB refering to here?
Note : I can very well add new CHANNEL_DETAILS after click add button.
I had this kind problem for the last two days and the problem was
1. If on adding details to a new form initially, you do not add the right field required.(I was including both text and integers to a field that was only CharField)
2.The other solution when the error came again was to delete migrations and the database itself and create a new database again(Using the same database name).
In my case, I had an existing SQLite database that I've been migration over to Django. All my entities had a UUID column as their primary key.
I had set the primary key column as django.models.UUIDField thinking that Django would support it, but it doesn't.
So I converted it to a text field with UUID as default value, it started working again.
class Model(models.Model):
# id = models.UUIDField(primary_key=True)
id = models.TextField(primary_key=True, default=uuid.uuid4)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
I have found in internet different examples on how to handle m2m relations with existing DB models, such as ex1 or here ex2, however I'm still not able to solve the error I get.
My models are depicted below. Basically, all the tables where created manually.
I got the following error message:
OperationalError: (1054, "Unknown column 'supervisor_project.id' in 'field list'").
I'm still a bit confused on when to use unique_together with through. Do you see any errors in the model below? The table supervisor_project has no id field and its PK is composed actually of two FK's, i.e. surrogate PK.
class Supervisor(models.Model):
name = models.CharField(max_length=45, blank=True, null=True, help_text="Name, e.g. John Smith")
class Meta:
managed = False
db_table = 'supervisor'
def __unicode__(self):
return self.name
class Project(models.Model):
title = models.CharField(max_length=45, blank=True, null=True)
supervisors = models.ManyToManyField(Supervisor, through='SupervisorProject', through_fields=('project', 'supervisor'))
class SupervisorProject(models.Model):
supervisor = models.ForeignKey('Supervisor', on_delete=models.CASCADE)
project = models.ForeignKey('Project', on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'supervisor_project'
unique_together = (('supervisor', 'project'),)
Django requires each model to have exactly one primary key field. It doesn't support multiple-column primary keys yet.
Since you haven't explicitly defined a primary key on the SupervisorProject model, Django assumes that there is an automatic primary key field id. When it includes the id field in a query, you get the error because it doesn't exist.
If possible, I would add an auto-incrementing id column to each intermediate table. There isn't a way to get Django to add the column to the tables automatically. You have set managed=False, so Django expects you to manage the database table.
I'm learning Django and trying to get the hang of querying foreign keys across a bridging table. Apologies if this is a duplicate, I haven't been able to find the answer by searching. I've got models defined as follows
class Place(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
class PlaceRef(models.Model):
place = models.ForeignKey(Place) # many-to-one field
entry = models.ForeignKey(Entry) # many-to-one field
class Entry(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=10)
If I want to retrieve all the Entries associated with a particular Place, how do I do it?
place = get_object_or_404(Place, id=id)
placerefs = PlaceRef.objects.filter(place=place)
entries = Entry.objects.filter(id.....)
Also, if there is a more sensible way for me to define (or get rid of) PlaceRefs in Django, please feel free to suggest alternatives.
Thanks for helping out a beginner!
First, I'd suggest rewriting the models to:
class Place(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=100)
class Entry(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=10)
places = models.ManyToManyField(Place, related_name='places')
So you can query:
Entry.objects.filter(places__id=id)
In your current model:
Entry.objects.filter(placeref_set__place__id=id)
Note that the double underscore __ is used to jump from one model to the next. Also, django creates some fields on the model that help you navigate to related objects. In this example: Entry.placeref_set. You can read more about it here:
http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
I've got Django tables like the following (I've removed non-essential fields):
class Person(models.Model):
nameidx = models.IntegerField(primary_key=True)
name = models.CharField(max_length=300, verbose_name="Name")
class Owner(models.Model):
id = models.IntegerField(primary_key=True)
nameidx = models.IntegerField(null=True, blank=True) # is Person.nameidx
structidx = models.IntegerField() # is PlaceRef.structidx
class PlaceRef(models.Model):
id = models.IntegerField(primary_key=True)
structidx = models.IntegerField() # used for many things and not equivalent to placeidx
placeidx = models.IntegerField(null=True, blank=True) # is Place.placeidx
class Place(models.Model):
placeidx = models.IntegerField(primary_key=True)
county = models.CharField(max_length=36, null=True, blank=True)
name = models.CharField(max_length=300)
My question is as follows. If in my views.py file, I have a Person referenced by name and I want to find out all the Places they own as a QuerySet, what should I do?
I can get this far:
person = Person.objects.get(name=name)
owned_relations = Owner.objects.filter(nameidx=nameidx)
How do I get from here to Place? Should I use database methods?
I'm also not sure if I should be using ForeignKey for e.g. Owner.nameidx.
Thanks and apologies for this extremely basic question. I'm not sure how to learn the basics of database queries except by trying, failing, asking SO, trying again... :)
The whole point of foreign keys is for uses like yours. If you already know that Owner.nameidx refers to a Person, why not make it a foreign key (or a OneToOne field) to the Person table? Not only do you get the advantage of referential integrity - it makes it impossible to enter a value for nameidx that isn't a valid Person - the Django ORM will give you the ability to 'follow' the relationships easily:
owned_places = Place.objects.filter(placeref__owner__person=my_person)
will give you all the places owned by my_person.
Incidentally, you don't need to define the separate primary key fields - Django will do it for you, and make them autoincrement fields, which is almost always what you want.
If u could redesign.Then
In owner nameidx can be a foreign key to Person(nameidx)
Placeref(structidx) could be a foreign key to Owner(structidx) and
Place(placeidx) could be a foreign key Place ref(placeidx)
Then u could deduce the place value easily..