Django (SQLite) - cannot access foreign key - no such column - custom sql - django

I am getting "no such column" whenever I try to access a foreign key. Here is a model:
class PerkLevel(models.Model):
perk_id = models.ForeignKey('Perk', on_delete=models.CASCADE, related_name='perk_id')
perk_level = models.IntegerField(default=1, choices=PERK_LEVELS)
perk_desc = models.CharField(max_length=250, null=True, blank=True)
class Meta:
db_table = u'pl'
When I try to execute a simple query like this:
cursor.execute("SELECT perk_id FROM pl")
I get "no such column: perk_id." How can I get the foreign key when writing my own sql?

Django adds its own _id to the end of foreign keys. In this case, I would use perk_id_id.

Related

How to remove relation from django model with ManyToMany field?

How to remove relation from model with ManyToMany field?
I've got a model with ManyToManyField relation. I need to remove relation but not data from the following model:
class TxHomes(models.Model):
user = models.ManyToManyField(settings.AUTH_USER_MODEL)
home_id = models.PositiveIntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length=255, null=True)
geo_name = models.CharField(max_length=255, null=True)
payload = models.JSONField()
Django ORM got tables generated:
-- auto-generated definition
create table main_txhomes
(
home_id integer unsigned not null primary key,
name varchar(255),
geo_name varchar(255),
...
);
create table main_txhomes_user
(
id primary key autoincrement,
txhomes_id ...,
user_id ...
);
When I apply to do that with a following code
TxHomes.objects.filter(
home_id__in=TxHomes.objects.filter(user=USER_ID).values('home_id')
,user=USER_ID).delete()
i got entire data deleted from main_txhomes
I want to keep data in main_txhomes table, what i need is to delete relations from main_txhomes_user table. How to do that?
Solution is found:
User.objects.get(id=USER_ID).txhomes_set.clear()
This is how we remove all relation to txhomes table for the user

How to add foreign key in table using existing column without losing data in django with sqlite3?

I want to alter some tables that have IntegerField type into a foreign key without losing any data. so, How can I do that in both sqlite3 and Django when I do makemigrations command?
this is models looks like:
class Sentences(models.Model):
actor_id = models.IntegerField(blank=True, null=True)
film_id = models.IntegerField(blank=True, null=True)
class Tokens(models.Model):
word_id = models.IntegerField(blank=True, null=True)
sentence_id = models.IntegerField(blank=True, null=True)
class Actors(models.Model):
...
class Words(models.Model):
...
class Films(models.Model):
...
every _id has IntegerField in the first place is referred to the actual id from another table but instead, I want to modify it to become ForeignKey instead of IntegerField how I do that modification?
id is a primary key for every table. It has unique values for each row. Foreign Key is the column that refers to the primary key of another table. To define Foreign Key refer the model name like
class Tokens(models.Model):
word = models.ForeignKey(Words, on_delete=models.CASCADE)
sentence = models.ForeignKey(Sentence, on_delete=models.CASCADE)
..........
After migrating your relation (Table) "Tokens" will have two columns 1. word_id and 2. sentence_id
Refer : https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_one/

ForeignKey updates aren't cascading on Django created tables in Postgres

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.

django throws error: Invalid column name 'id' (SQL SERVER)

I try to create a web app using django and connecting to a SQL Server Database. The table that I use to display the data in a django form consists of 2 columns. Both of them being a foreign key and both of them together building the primary key of the table
CREATE TABLE [dbo].[MyTable]( [ID_Field1] [int] NOT NULL,
[ID_Field2] [int] NOT NULL, CONSTRAINT [PK_Movies2Genres] PRIMARY
KEY CLUSTERED ( [ID_Field1] ASC, [ID_Field2] ASC )WITH (PAD_INDEX =
OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON
[PRIMARY]
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [FK_Field2]
FOREIGN KEY([ID_Field2]) REFERENCES [dbo].[Table2] ([ID_Field2])
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_Field2]
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [FK_Field1]
FOREIGN KEY([ID_Field1]) REFERENCES [dbo].[Table1] ([ID_Movie])
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_Field1]
Now, django apperantly cannot create a model corresponding to this kind of sql table structure, i.e. it cannot create a primary key consisting of more than one field. Instead, it sets the primary key on one of the 2 columns and in the meta section of the model class it sets
unique_together = (('id_field1', 'id_field2'),)
The complete model:
class MyTable(models.Model):
id_field1 = models.ForeignKey(Table1, on_delete=models.DO_NOTHING, db_column='ID_Field1')
id_field2 = models.ForeignKey(Table2, on_delete=models.DO_NOTHING, db_column='ID_Field2')
class Meta:
managed = False
db_table = 'MyTable'
unique_together = (('id_field1', 'id_field2'),)
However, this is what django inspectdb tells me to do. I know that django creates automatically a field called id when there is no primary key defined. This seems to be the case here, although there is a primary key defined. Any idea how to deal with that problem?
use: https://github.com/onysos/django-composite-foreignkey
class Customer(models.Model):
company = models.IntegerField()
customer_id = models.IntegerField()
name = models.CharField(max_length=255)
address = CompositeForeignKey(Address, on_delete=CASCADE, to_fields={
"tiers_id": "customer_id",
"company": LocalFieldValue("company"),
"type_tiers": RawFieldValue("C")
})
class Meta(object):
unique_together = [
("company", "customer_id"),
]
class Contact(models.Model):
company_code = models.IntegerField()
customer_code = models.IntegerField()
surname = models.CharField(max_length=255)
# virtual field
customer = CompositeForeignKey(Customer, on_delete=CASCADE, related_name='contacts', to_fields={
"customer_id": "customer_code",
"company": "company_code"
})

m2m for existing table (through/unique_together)

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.