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

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"
})

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

Declaring foreign key in django model

I have recently started using django to read out oracle database. I am having a problem with created a model with foreign key.
Here is what I have in Oracle schema:
CREATE TABLE MTRS_CHANNELS(ID int NOT NULL PRIMARY KEY, ALIAS VARCHAR(255) NOT NULL UNIQUE, BOARDNUMBER int, CHIPNUMBER int, CHANNELNUMBER int, TYPEID int, SYSTEMNAME VARCHAR(255));
ALTER TABLE MTRS_CHANNELS ADD CONSTRAINT uniquesensornaming UNIQUE (BOARDNUMBER , CHIPNUMBER , CHANNELNUMBER, SYSTEMNAME);
CREATE TABLE MTRS_DATA(CHANNELID int NOT NULL, FLAG int, UPDATETIME TIMESTAMP, VALUE FLOAT);
ALTER TABLE MTRS_DATA ADD CONSTRAINT CHANNELIDENTIFIER FOREIGN KEY (CHANNEL_ID) REFERENCES MTRS_CHANNELS(ID);
Basically there are 2 tables MTRS_CHANNELS which stores channels identified by unique channelid and MTRS_DATA stores value for a channel, which is referenced by channelid as foreign key.
In my models.py I have :
from django.db import models
class Channel(models.Model):
id = models.IntegerField(primary_key=True)
alias = models.CharField(max_length=256)
boardnumber = models.IntegerField()
chipnumber = models.IntegerField()
channelnumber = models.IntegerField()
typeid = models.IntegerField()
systemname = models.CharField(max_length=255)
class Meta:
db_table = "MTRS_CHANNELS"
managed = False
class values(models.Model):
channel = models.ForeignKey(Channel,on_delete=models.CASCADE)
updatetime = models.DateTimeField()
value = models.FloatField()
class Meta:
db_table = "MTRS_DATA"
managed = False
The problem is that I am trying to load data in view it complains with:
ORA-00904: "MTRS_DATA"."ID": invalid identifier
When I try to modify channel to channel_id in values, I get
ORA-00904: "MTRS_DATA"."CHANNEL_ID_ID": invalid identifier
I might be missing something really obvious but the problem clearly comes from the way Foreign Key is declared.
Thanks and regards,
Ivan

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 (SQLite) - cannot access foreign key - no such column - custom sql

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.

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.