django.db.utils.ProgrammingError: relation "postgres_po_db_view" already exists - django

am developing an api based on database view and am trying to a create a model for the same postgres database view with managed=False option in class meta of model, and am connecting my model via db_table parameter in the same class meta, here my database view name is "postgres_po_db_view" and am getting an error when ever am trying to run migrations for the corresponding model, please don't bother about the view or the model code, everything is good and working but my concern is when ever am trying to connect my model with my database view through class meta configuration inside the model class,when i migrated the very first time it is running smooth, and then after trying to run one more migration for another model or again trying to run the same command migrate am getting relation postgres_po_db_view already exists error...any useful lead is much appreciable..am unable to apply further migrations due to this error...
here is my model:
class ProductionOrderView(models.Model):
class Meta:
managed = False,
ordering = '-creation_time',
db_table = 'postgres_po_db_view'
DRAFT = 'draft'
PLANNING = 'planning'
NOT_STARTED = 'not_started'
IN_PROGRESS = 'in_progress'
CANCELLED = 'cancelled'
DONE = 'done'
FAILED = 'failed'
STATUS_CHOICES = (
(DRAFT, 'Draft'),
(PLANNING, 'Planning'),
(NOT_STARTED, 'Not Started'),
(IN_PROGRESS, 'In Progress'),
(CANCELLED, 'Cancelled'),
(DONE, 'Done'),
(FAILED, 'Failed'),
)
ACTIVE_STATUS_LIST = [DRAFT, IN_PROGRESS, PLANNING]
id = models.UUIDField(
default=uuid.uuid4,
primary_key=True,
editable=False,
unique=True,
)
name = models.CharField(
max_length=64,
default = '',
blank = True,
)
deadline = models.DateTimeField(**NB)
planned_date = models.DateTimeField(**NB)
print_date = models.DateTimeField(**NB)
build = models.CharField(
max_length=256,
default='',
blank=True,
)
sop = models.CharField(
max_length=128,
default='',
blank=True,
)
notes = models.CharField(
max_length=256,
default='',
blank=True,
)
build_qty = models.IntegerField(default=0)
status = models.CharField(
max_length=64,
default='',
)
last_updated_by =models.CharField(
max_length=64,
default='',
)
site = JSONField(
default=dict
)
site_id = models.CharField(
max_length=64,
default='',
)
production_type = models.CharField(
max_length=64,
default='',
blank=True,
)
operation_failures = JSONField(
default=dict
)
operation_status = JSONField(
default=dict
)
files = JSONField(
default=dict
)
sap_backflush_submission_status = models.BooleanField(default=False)
creation_time = models.DateTimeField(**NB)
update_time = models.DateTimeField(**NB)
here is my postgres data base view:
create or replace view postgres_po_db_view as
(select po.id,po.name as name),
(po.institution_id as institution),
(po.deadline),
(po.planned_date),
(po.print_date),
(po.status),
(po.production_type),
(po.notes),
(po.creation_time),
(po.update_time),
(Select bu.name from skyforge_build as bu where bu.id = po.build_id) as build,
(Select so.name from skyforge_sop as so where so.id = po.sop_id) as sop,
(select json_agg(site) from (Select si.name,si.id from skyforge_site as si where si.id=po.site_id) as site) as site,
(Select us.first_name from auth_user as us where us.id=po.last_updated_by_id) as last_updated_by,
(Select sum(quantity) from skyforge_buildpart as bup where bup.build_id=po.build_id) as build_qty,
(select json_agg(totrecs) as operation_fail_list from (select operation_id,array_agg(id) as operation_failures from skyforge_failure as fail where ROW(operation_id) in (select id from skyforge_operation as op where op.production_order_id = po.id) group by fail.operation_id) as totrecs) as operation_failures,
(select json_agg(json_build_object(op.id,op.status)) from skyforge_operation as op where op.production_order_id = po.id) as operation_status,
(select json_agg(vtorecs) from (select id,name,content from skyforge_file group by id having parent_id=po.id union select id,name,content from (select fi.id,fi.name,fi.content,po.id as poid from skyforge_file as fi,skyforge_productionorder as po where fi.id in (po.backflush_id,po.pdf_id,po.inspection_template_full_id,po.inspection_template_sampling_id,po.production_slips_id,po.serialized_part_tags_id,po.batches_qr_labels_id)) as recs where recs.poid=po.id) as vtorecs) as files,
(po.sap_backflush_submission_status)
From skyforge_productionorder as po;

Related

When "select_related" is needed?

In my project , Each candidate can takepart in some assessments,each assessment has some tests, each test has some questions in it and candidates should answer the questions
at last scores of the questions are saved in question_score and test_score table
I need to get some values of field and use them
I write a method for question_result table, to get them
but i dont know if it is needed to use select_related or not
if it is needed how can i use it ?
Assessment:
class Assessment(BaseModel):
company = models.ForeignKey(
'company.Company',
on_delete=models.CASCADE,
related_name='assessments',
)
title = models.CharField(max_length=255)
job_role = models.ForeignKey(
JobRole,
on_delete=models.PROTECT,
related_name='assessments',
blank=True,
null=True,
)
tests = models.ManyToManyField(
'exam.Test',
related_name='assessments',
blank=True,
through='TestOfAssessment',
)
candidates = models.ManyToManyField(
'user.User',
related_name='taken_assessments',
blank=True,
through='candidate.Candidate'
)
def __str__(self):
return self.title
Test:
class Test(BaseModel):
class DifficultyLevel(models.IntegerChoices):
EASY = 1
MEDIUM = 2
HARD = 3
company = models.ForeignKey(
'company.Company',
on_delete=models.PROTECT,
related_name='tests',
null=True,
blank=True,
)
questions = models.ManyToManyField(
'question.Question',
related_name='tests',
blank=True,
help_text='Standard tests could have multiple questions.',
)
level = models.IntegerField(default=1, choices=DifficultyLevel.choices)
title = models.CharField(max_length=255)
summary = models.TextField()
def __str__(self):
return self.title
Question :
class Question(BaseModel):
company = models.ForeignKey(
'company.Company',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='company_questions',
)
question_text = models.TextField()
def __str__(self):
return truncatewords(self.question_text, 7)
TestResult:
class TestResult(BaseModel):
candidate = models.ForeignKey(
'Candidate',
on_delete=models.CASCADE,
related_name='test_results',
)
test = models.ForeignKey(
'exam.Test',
on_delete=models.CASCADE,
)
test_score = models.DecimalField(default=0.00, max_digits=5, decimal_places=2)
def __str__(self):
return f'{self.candidate.user.email} - {self.test.title}'
Candidate :
class Candidate(BaseModel):
assessment = models.ForeignKey(
'assessment.Assessment',
on_delete=models.CASCADE,
)
user = models.ForeignKey(
'user.User',
on_delete=models.CASCADE,
)
is_rejected = models.BooleanField(default=False)
def __str__(self):
return f'{self.user.email} - {self.assessment.title}'
Company :
class Company(models.Model):
manager = models.ForeignKey('user.User', on_delete=models.CASCADE, related_name='user_companies')
name = models.CharField(max_length=255)
city = models.ForeignKey('company.City', null=True, on_delete=models.SET_NULL)
address = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return self.name
QuestionResult :
class QuestionResult(BaseModel):
test = models.ForeignKey(
'TestResult',
on_delete=models.CASCADE,
related_name='question_results',
)
question = models.ForeignKey(
'question.Question',
on_delete=models.CASCADE,
related_name='results',
)
result = models.TextField(
null=True,
blank=True,
)
answer_score = models.DecimalField(default=0.00, max_digits=5, decimal_places=2)
def __str__(self):
return f'{self.test.candidate.user.email} - {self.question}'
def text_variables(self):
email = self.test.candidate.user.email
company_name = self.test.test.company.name
assessment_name = self.test.candidate.assessment.title
candidate_first_name = self.test.candidate.user.first_name
job_name = self.test.candidate.assessment.job_role
user_fullname = User.full_name
data = dict(
job_name=job_name,
company_name=company_name,
email=email,
assessment_name=assessment_name,
candidate_first_name=candidate_first_name,
job_name=job_name,
user_fullname = user_fullname
)
return data
I wrote the def text_variables(self): method to fill the data dictionary and use it somewhere else
it work properly but i dont know if it needed to use selected_related or not
something like this (it does not work)
def text_variables(self):
question_result_object = QuestionResult.objects.filter(id=self.id).select_related(
"test__candidate","test__test__company","test__candidate__assessment")
email = question_result_object.test.candidate.user.email
company_name = question_result_object.test.test.company.name
assessment_name = question_result_object.test.candidate.assessment.title
candidate_first_name = question_result_object.test.candidate.user.first_name
job_name = question_result_object.test.candidate.assessment.job_role
data = dict(
job_name=job_name,
company_name=company_name,
email=email,
assessment_name=assessment_name,
candidate_first_name=candidate_first_name,
job_name=job_name,
user_fullname = user_fullname
)
return data
the error is :
File "E:\work\puzzlelity\talent-backend\candidate\models.py", line 385, in report_to_candidate_email_text_variables
email = question_result_object.test.candidate.user.email
AttributeError: 'QuerySet' object has no attribute 'test'
[03/Jan/2023 17:59:00] "POST /api/v1/candidatures/183f8432-ea81-4099-b211-3b0e6475ffab/submit-answer/ HTTP/1.1" 500 123319
I dont know how should i use the select_related
It's never required. It optimizes querysets, especially in ListViews.
Consider your Assessment model. It has ForeignKey fields company and job_role. If you simply fetch
assessment = Assessment.objects.get( id=something)
and then refer to assessment.company, that causes a second DB query to fetch the company object. And then a third if you refer to assessment.job_role.
You can reduce these three queries to one by using
assessment = Assessment.objects.select_related(
'company', 'job_role') .get( id=something)
which does a more complex query to retrieve all the data.
Where it matters is in a list view where you iterate over a large number of assessment objects in Python or in a template. For example, if object_list is assessment.objects.all() and there are 300 of them, then
{% for assessment in object_list %}
... stuff ...
{{assessment.company.name }}
...
{% endfor %}
Will hit the DB 300 times, once for each company! If you use select_related, all 300 companies linked to the 300 assessments will be retrieved in a single DB query. which will be very noticeably faster.
I'd strongly recommend installing Django Debug Toolbar in your development project. Then click on the SQL option on any view, and you can see what SQL was required, and in particular how many SQL queries were performed and whether there were batches of repetetive queries which mean there's a trivial optimisation to be made.

How to access the value of a foreign key in a table in django?

I've 2 tables in a database on phpmyadmin that are connected by a foreign key. The table "bulle" contains the foreign key of the table "site". In enghlish : one "site" can contain some "bulles" (or not) and a "bulle" is always linked to a "site".
class Bulles(models.Model):
id_bulle = models.AutoField(primary_key=True)
num_bulle = models.CharField(max_length=20)
type_bulle = models.CharField(max_length=20)
colories = models.CharField(max_length=20)
latitude = models.FloatField()
longitude = models.FloatField()
date_vidange = models.DateField(
db_column="date_vidange"
)
id_depot = models.ForeignKey(
"Depot", on_delete=models.CASCADE, db_column="id_depot"
)
id_site = models.ForeignKey(
"Site",related_name='bul', on_delete=models.CASCADE, db_column="Id_site"
)
class Meta:
db_table = "bulles"
class Site(models.Model):
id_site = models.AutoField(
db_column="Id_site", primary_key=True
)
nom = models.CharField(
db_column="Nom", max_length=100
)
vitesse_b = models.FloatField(db_column="Vitesse_b") # Field name made lowercase.
vitesse_c = models.FloatField(db_column="Vitesse_c") # Field name made lowercase.
ecart_type_b = models.FloatField(
db_column="Ecart_type_b"
)
ecart_type_c = models.FloatField(
db_column="Ecart_type_c"
)
type_site = models.CharField(
db_column="Type_site", max_length=20
)
longitude = models.FloatField(db_column="Longitude")
latitude = models.FloatField(db_column="Latitude")
Nombre_bulles = models.IntegerField(db_column="Nombre_bulles")
date_vidange = models.DateField(
db_column="Date_vidange")
class Meta:
db_table = "site"
I've created a request to delete a row in "bulle" selected by the id_bulle (primary key). I'd like to get the "id_site" from this selected bulle that I delete in this request. Then, I need to count every "bulles" of the table that have this id_site. After that I would like to change the value of the column "Nombre_bulles" by the number found just before.
def DeleteBulle (request, id_bulle):
try:
id_bulle
param = Bulles.objects.get(pk=id_bulle)
param.delete()
print("Bulle supprimée")
except:
print("Cette bulle n'existe pas")
return redirect('api_bulles_frontend')
return redirect('api_bulles_frontend')
I don't know how to access the value of the Id_site of the "bulle" I'm deleting selected by its id.
I'm sorry for my english, I hope someone here can help me.
Thanks !
I really don't know how I could do that, I can't find it on Internet.
param.id_site.somethingFromTheClass

django: smart-select ChainedForeignKey / chained dropdown in admin

Hej! :)
I have 5 models which are connected hierarchical with each other.
Section -> division -> group -> class -> wz
one section can have multiple divisions, but one division can only have one section (and so on). Therefor I have ForeignKeys set:
# models.py
class NaceSection(models.Model):
code = models.CharField(max_length=1, unique=True)
description_english = models.CharField(max_length=500)
class NaceDivision(models.Model):
code = models.CharField(max_length=2, unique=True)
nace_section = models.ForeignKey(NaceSection, on_delete=models.CASCADE, related_name="nace_section")
description_english = models.CharField(max_length=500)
class NaceGroup(models.Model):
nace_division = models.ForeignKey(NaceDivision, on_delete=models.CASCADE, related_name="nace_division")
code = models.CharField(max_length=4, unique=True)
description_english = models.CharField(max_length=500)
I than have a model where all those are integrated as M2M fields with a dropdown option.
My goal is to only get the divisions which are in the already selected section in the admin area. (and so on)
I tried smart-select ChainedForeignKey:
# models.py
class Institution(models.Model):
nace_sections = models.ManyToManyField(
NaceSection,
related_name="nace_sections"
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_sections',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_divisions',
blank=True,
)
The organisation and dropdown in the admin area do not change at all and my view with a table of all my results tells me ('42S22', "[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'nace_divisions_id'. (207) (SQLExecDirectW)")
With the ChainedManyToManyField nothing at all happens. Does anybody know what's going wrong?
Any help appreciated! :)
nace_sections is specified as models.ManyToManyField in your code
1.Change from ManyToManyField to ForeignKey.
2.Rename chained_model_field values
-->nace_sections to nace_section
-->nace_divisions to nace_division
class Institution(models.Model):
nace_sections = models.ForeignKey(
NaceSection,
related_name="nace_sections"
, on_delete=models.CASCADE
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_section',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_division',
blank=True,
)

Need help translating raw sql query to ORM Django

Django Models that used in projects:
class LeadStatus(models.Model):
status_id = models.PositiveIntegerField(verbose_name='ID статуса', unique=True)
name = models.CharField(max_length=100, verbose_name='Имя', null=True, default='Неизвестный')
class Lead(models.Model):
lead_id = models.PositiveIntegerField(verbose_name="ID сделки", null=True, unique=True)
created_date_time = models.DateTimeField(verbose_name="Время и дата создания сделки", null=True)
price = models.IntegerField(verbose_name='Бюджет сделки')
current_status = models.ForeignKey(LeadStatus, on_delete=models.SET_NULL, verbose_name='Текущий статус', null=True)
class LeadsNote(models.Model):
note_id = models.CharField(verbose_name="ID примечания", null=True, unique=True, max_length=64)
lead = models.ForeignKey(Lead, on_delete=models.CASCADE)
old_status = models.ForeignKey(LeadStatus, related_name='old_status', null=True, blank=True,
on_delete=models.CASCADE)
new_status = models.ForeignKey(LeadStatus, null=True, related_name='new_status', blank=True,
on_delete=models.CASCADE)
crossing_status_date_time = models.DateTimeField(verbose_name="Время и дата пересечения статуса", null=True)
I am trying to execute the following SQL query using Django ORM tools. He does what i need
SELECT leads.id,
notes.crossing_status_date_time,
old_status.name as old_status,
new_status.name as new_status,
(CASE WHEN leads.id in (
select leads.id
from core_leads
where old_status.status_id not in (13829322, 14286379) and new_status.status_id in (13829322, 14286379))
THEN true ELSE false END) as _is_profit
FROM core_leadsnote AS notes
LEFT JOIN core_lead AS leads ON notes.lead_id=leads.id
LEFT JOIN core_leadstatus AS old_status ON notes.old_status_id=old_status.id
LEFT JOIN core_leadstatus AS new_status ON notes.new_status_id=new_status.id
Using Django subqueries I came up with the following ORM query.
But it doesn't work as well as raw sql
from django.db.models import OuterRef, Q, Subquery, Case, When, BooleanField
from .models import LeadsNote, Lead, CompanyConfig, AmoCompany
company = AmoCompany.objects.first()
status_config = CompanyConfig.objects.get(company=company)
accepted_statuses = [status.status_id for status in status_config.accept_statuses.all()]
subquery = (Lead
.objects.select_related('current_status', 'company')
.filter(leadsnote=OuterRef('pk'))
.filter(~Q(leadsnote__old_status__status_id__in=accepted_statuses) &
Q(leadsnote__new_status__status_id__in=accepted_statuses)))
query = (LeadsNote
.objects
.annotate(
_is_profit=Case(
When(lead__id__in=Subquery(subquery.values('id')), then=True),
default=False, output_field=BooleanField())))
Need any help finding the right solution

Creating a one-to-many relationship with a pre-existing database with records

I am trying to create a one-to-many relationship between the YahooTickerSymbol and PriceHistory database. However, I already have some data in the PriceHistory database without any keys relating to the YahooTickerSymbol database. Is there a way to create the relationship without violating the foreign key constraint?
class YahooTickerSymbols(models.Model):
yahoo_ticker_number = models.AutoField(primary_key=True, )
yahoo_ticker_symbol = models.CharField(max_length=20, )
yahoo_company_name = models.CharField(max_length=120, )
class Meta:
ordering = ['yahoo_company_name', ]
verbose_name_plural = "Yahoo Ticker Symbols"
def __str__(self):
return "%s is %s." % (self.yahoo_company_name, self.yahoo_ticker_symbol)
class PriceHistory(models.Model):
price_data_number = models.AutoField(primary_key=True, )
yahoo_ticker_symbol = models.CharField(max_length=20, )
price_date = models.DateField(auto_now=False, auto_now_add=False, )
price_open = models.DecimalField(max_digits=7, decimal_places=3, )
price_high = models.DecimalField(max_digits=7, decimal_places=3, )
price_low = models.DecimalField(max_digits=7, decimal_places=3, )
price_close = models.DecimalField(max_digits=7, decimal_places=3, )
price_adjusted_close = models.DecimalField(max_digits=7, decimal_places=3, )
price_volume = models.BigIntegerField()
yahootickersymbol = models.ForeignKey(YahooTickerSymbols, blank=True, null=True,
on_delete=models.SET_NULL, )
class Meta:
ordering = ['yahoo_ticker_symbol', 'price_date', ]
verbose_name_plural = "Historical Prices"
def __str__(self):
return "%s - %s : %s" % (self.yahoo_ticker_symbol, self.price_date, self.price_close)
The code in the migration file is as follows:
class Migration(migrations.Migration):
dependencies = [
('investments', '0009_auto_20160124_1517'),
]
operations = [
migrations.AlterField(
model_name='pricehistory',
name='yahootickersymbol',
field=models.ForeignKey(to='investments.YahooTickerSymbols', on_delete=django.db.models.deletion.SET_NULL, null=True, blank=True),
),
]
I realized that I made a mistake in the process of running the makemigrations command.
Previously, I did not set null=True for models.ForeignKey and I ran the makemigrations command. After realizing my error, I included null=True within models.py. However, I did not delete the previous migration files. As such, Django was stuck in trying to run the old migration files even though these were not possible to be effected.
To resolve this, you need to run showmigrations to understand which migration files have not been included to understand the root of the problem.