Django Foreign key constraint error on submitting a row - python

I just created a Django Project and added 2 directly in mysql:
1) Financial Holdings (tbl_holdings)
2) Service Providers (tbl_holdings_service_providers)
Both of their Data Definitions in My Sql are:
tbl_holdings
CREATE TABLE `tbl_holdings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_code` varchar(5) NOT NULL,
`product_name` varchar(45) NOT NULL,
`service_provider` varchar(100) NOT NULL,
`account_details` varchar(100) NOT NULL,
`purchase_cost` int(15) NOT NULL,
`current_value` int(15) NOT NULL,
`purchase_date` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `item_code_UNIQUE` (`item_code`),
KEY `fk_service_provider_name_idx` (`service_provider`),
CONSTRAINT `fk_service_provider` FOREIGN KEY (`service_provider`) REFERENCES `tbl_holdings_service_providers` (`provider_name`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
tbl_holdings_service_providers
CREATE TABLE `tbl_holdings_service_providers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`provider_name` varchar(100) NOT NULL,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `INDEX` (`provider_name`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1
I created the related model in Django models.py
class TblHoldings(models.Model):
item_code = models.CharField(unique=True, max_length=5)
product_name = models.CharField(max_length=45)
service_provider = models.ForeignKey('TblHoldingsServiceProviders', models.DO_NOTHING, related_name='service_provider',db_column='service_provider')
account_details = models.CharField(max_length=100)
purchase_cost = models.IntegerField()
current_value = models.IntegerField()
purchase_date = models.DateTimeField(blank=True, null=True)
updated_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
class Meta:
verbose_name = 'Holding'
verbose_name_plural = 'Holdings'
managed = False
db_table = 'tbl_holdings'
class TblHoldingsServiceProviders(models.Model):
provider_name = models.CharField(max_length=100)
updated_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
class Meta:
verbose_name = "Lookup For Service Provider"
verbose_name_plural = 'Lookup For Service Providers'
managed = False
db_table = 'tbl_holdings_service_providers'
and the code in admin.py is
#admin.register(TblHoldings)
class HoldingsAdmin(admin.ModelAdmin):
list_display = ('item_code', 'product_name', 'service_provider', 'current_value', 'created_at')
ordering = ('purchase_date',)
search_fields = ('product_name',)
#admin.register(TblHoldingsServiceProviders)
class HoldingsServiceProviderAdmin(admin.ModelAdmin):
list_display = ('id', 'provider_name', 'created_at')
ordering = ('created_at',)
search_fields = ('provider_name',)
On trying to add a holding I get the below error: pertaining to the foreign key constraint
IntegrityError at /admin/app_fin/tblholdings/add/ (1452, 'Cannot add
or update a child row: a foreign key constraint fails
(_finance.tbl_holdings, CONSTRAINT fk_service_provider
FOREIGN KEY (service_provider) REFERENCES
tbl_holdings_service_providers (provider_name) ON DELETE NO ACTION
ON UPDATE )') Request Method: POST Request
URL: admin/app_fin/tblholdings/add/ Django
Version: 2.2.7 Exception Type: IntegrityError Exception Value: (1452,
'Cannot add or update a child row: a foreign key constraint fails
(_finance.tbl_holdings, CONSTRAINT fk_service_provider
FOREIGN KEY (service_provider) REFERENCES
tbl_holdings_service_providers (provider_name) ON DELETE NO ACTION
ON UPDATE )') Exception
Location: /root//venv/lib/python3.6/site-packages/MySQLdb/connections.py
in query, line 231 Python
Executable: /root//venv/bin/python Python Version: 3.6.8
Python Path: ['/root//project_',
'/root//venv/lib/python36.zip',
'/root//venv/libremoved/python3.6',
'/root//venv/lib/python3.6/lib-dynload',
'/usr/lib/python3.6',
'/root/_fin/venv/lib/python3.6/site-packages'] Server
time: Tue, 12 Nov 2019 09:51:28 +0000
Can someone point me to what I am doing wrong.

Looks like the foreign key you are using is not a primary key. You can try this out
CREATE TABLE `tbl_holdings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`item_code` varchar(5) NOT NULL,
`product_name` varchar(45) NOT NULL,
`service_provider` varchar(100) NOT NULL,
`account_details` varchar(100) NOT NULL,
`purchase_cost` int(15) NOT NULL,
`current_value` int(15) NOT NULL,
`purchase_date` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `item_code_UNIQUE` (`item_code`),
KEY `fk_service_provider_name_idx` (`service_provider`),
CONSTRAINT `fk_service_provider` FOREIGN KEY (`service_provider`) REFERENCES `tbl_holdings_service_providers` (`provider_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

Related

default value dont work in sqlalchemy python

Good day!
This is my table
class My_table(Base):
__tablename__ = 'table'
__table_args__ = {'mysql_engine': 'InnoDB',
"mysql_collate": "utf8mb4_general_ci",
"mysql_charset": "utf8mb4"}
id = Column(INTEGER(unsigned=True), primary_key=True, autoincrement=True)
sport = Column(VARCHAR(30), nullable=False)
active = Column(TINYINT(), nullable=False, default=1, server_default=text('1'))
this is result of model
CREATE TABLE `table` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`sport` varchar(30) COLLATE utf8mb4_general_ci NOT NULL,
`active` tinyint NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
sport = {'sport': Football, 'active': 0 }
sport1 = {'sport': Football}
If i add dict sport then all good , but if i try add sport1 then i got pymysql.err.IntegrityError: (1048, "Column 'active' cannot be null")
If
active = Column(TINYINT(), default='1', server_default=text('1'))
active = Column(TINYINT(), default=1, server_default=text('1'))
active = Column(TINYINT(), default='1', server_default='1')
Then in base column active have NULL. How does it work and what am I doing wrong ?

Integrity Error when creating multiple records with Flask SqlAlchemy

I have a function that creates some new DB entries in Flask app with SQL Alchemy
def add_volunteer_client_record(volunteer_id, **kwargs):
try:
volunteer_client = VolunteerClient(volunteer_id=volunteer_id, **kwargs)
volunteer_report_action_items = VolunteerReportActionItems(volunteer_client_id = volunteer_client.id)
db_session.add(volunteer_client)
db_session.add(volunteer_report_action_items)
db_session.commit()
return volunteer_client
except IntegrityError as e:
db_session.rollback()
message = "Integrity error occurred"
raise BadRequestError(messages={'volunteer_client': [message]})
volunteer_client gets created fine but when volunteer_report_action_items is added to the session I received an IntegrityError and I can not quite understand why.
My Models
class VolunteerClient(Base):
__tablename__ = 'volunteer_client'
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
volunteer_id = Column(Integer, ForeignKey('provider_user.user_id', onupdate='CASCADE', ondelete='RESTRICT'), unique=True)
client_id = Column(Integer, ForeignKey('user.id', onupdate='CASCADE', ondelete='RESTRICT'), unique=True)
class VolunteerReportActionItems(Base):
__tablename__ = 'volunteer_report_action_items'
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
volunteer_client_id = Column(Integer, ForeignKey('volunteer_client.id', onupdate='CASCADE', ondelete='RESTRICT'))
SQL
CREATE TABLE IF NOT EXISTS public.volunteer_client
(
id serial PRIMARY KEY,
volunteer_id integer NOT NULL,
client_id integer NOT NULL,
created_by text,
created_at timestamp NOT NULL DEFAULT now(),
updated_by text,
updated_at timestamp NOT NULL DEFAULT now(),
UNIQUE(volunteer_id, client_id),
CONSTRAINT fk_volunteer_client_volunteer FOREIGN KEY (volunteer_id)
REFERENCES public.user (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk_volunteer_client_client FOREIGN KEY (client_id)
REFERENCES public.user (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT
);
ALTER TABLE public.volunteer_client OWNER to navigate;
CREATE TABLE IF NOT EXISTS public.volunteer_report_action_items
(
id serial PRIMARY KEY,
volunteer_client_id integer NOT NULL,
created_by text,
created_at timestamp NOT NULL DEFAULT now(),
updated_by text,
updated_at timestamp NOT NULL DEFAULT now(),
CONSTRAINT fk_volunteer_report_action_items_volunteer_client FOREIGN KEY (volunteer_client_id)
REFERENCES public.volunteer_client (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT
);
ALTER TABLE public.volunteer_report_action_items OWNER to navigate;
Any help or advice here would be great. Thanks!
You need to flush the VolunteerClient to be able to access the VolunteerClient.id
def add_volunteer_client_record(volunteer_id, **kwargs):
try:
volunteer_client = VolunteerClient(volunteer_id=volunteer_id, **kwargs)
db_session.add(volunteer_client)
db_session.flush()
volunteer_report_action_items = VolunteerReportActionItems(volunteer_client_id = volunteer_client.id)
db_session.add(volunteer_report_action_items)
db_session.commit()
...

Foreign Keys not lining up in raw SQL and FLASK SQL Alchemy

I have somewhat of a general question, also curious about best practices. I have a model in SQL which looks as so:
CREATE TABLE IF NOT EXISTS public.volunteer_report
(
id serial PRIMARY KEY,
volunteer_id integer NOT NULL,
client_id integer NOT NULL,
user_need_id integer NOT NULL,
report character varying(255) NOT NULL,
report_category character varying(255) NOT NULL,
created_by text,
created_at timestamp NOT NULL DEFAULT now(),
updated_by text,
updated_at timestamp NOT NULL DEFAULT now(),
CONSTRAINT fk_volunteer_report_volunteer FOREIGN KEY (volunteer_id)
REFERENCES public.user (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk_volunteer_report_client FOREIGN KEY (client_id)
REFERENCES public.user (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk_volunteer_report_client_need FOREIGN KEY (user_need_id)
REFERENCES public.user_need (id) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT
);
Both FK's make a reference to the user PK.
MY FLASK APP
class VolunteerReport(Base):
__tablename__ = 'volunteer_report'
id = Column(Integer, primary_key=True, autoincrement=True, index=True)
volunteer_id = Column(Integer, ForeignKey('volunteer_client.volunteer_id', onupdate='CASCADE', ondelete='RESTRICT'))
client_id = Column(Integer, ForeignKey('volunteer_client.client_id', onupdate='CASCADE', ondelete='RESTRICT'))
user_need_id = Column(Integer, ForeignKey('user_need.id', onupdate='CASCADE', ondelete='RESTRICT'))
report = Column(String(255), nullable=False)
report_category = Column(String(255), nullable=False)
The FK references are different here. referencing volunteer_client table instead of user table, but the int FK value that gets stored is the same.
Is this expected to work and perform fine, or should the table references be exactly identical?

django model foreign key created index

I am creating models in django. This is my config in the models file. I want to create a table governmentoffical that references counties and citizen. However, when I ran manage.py sqlal, it changed my column name in government official tables.
class counties(models.Model):
name = models.CharField(max_length=50, primary_key=True, unique=True)
population = models.IntegerField()
governer = models.CharField(max_length=75)
class citizen(models.Model):
ssn = models.CharField(max_length=40, primary_key=True)
citizen_name = models.CharField(max_length=50, unique=True)
age = models.IntegerField()
income = models.IntegerField()
username = models.CharField(max_length=30)
password = models.CharField(max_length=30)
class governmentOfficial(models.Model):
countyName = models.ForeignKey(counties, primary_key=True)
offical_name = models.ForeignKey(citizen, to_field='citizen_name')
position = models.CharField(max_length=50)
year_elected = models.IntegerField(max_length=4)
party = models.CharField(max_length=25)
county_username=models.CharField(max_length=20)
county_password=models.CharField(max_length=20)
Here is my sql output.
CREATE TABLE `troywebsite_governmentofficial` (
`countyName_id` varchar(50) NOT NULL PRIMARY KEY,
`offical_name_id` varchar(50) NOT NULL,
`position` varchar(50) NOT NULL,
`year_elected` integer NOT NULL,
`party` varchar(25) NOT NULL,
`county_username` varchar(20) NOT NULL,
`county_password` varchar(20) NOT NULL
)
;
ALTER TABLE `troywebsite_governmentofficial` ADD CONSTRAINT `countyName_id_refs_name_2c9a2c94` FOREIGN KEY (`countyName_id`) REFERENCES `troywebsite_counties` (`name`);
ALTER TABLE `troywebsite_governmentofficial` ADD CONSTRAINT `offical_name_id_refs_citizen_name_6f795c2a` FOREIGN KEY (`offical_name_id`) REFERENCES `troywebsite_citizen` (`citizen_name`);
CREATE INDEX `troywebsite_governmentofficial_effdd6a5` ON `troywebsite_governmentofficial` (`offical_name_id`);
CREATE INDEX `troywebsite_solider_c5b4e228` ON `troywebsite_solider` (`solider_name_id`);
Is there a way to take out the CREATE INDEX in governmentofficial, and leave to to be countyName and Official_name as the column?
You can use the db_column parameter to call the column whatever you like.
https://docs.djangoproject.com/en/dev/ref/models/fields/#db-column
countyName = models.ForeignKey(counties, primary_key=True, db_column='whatever')

django database many2many relationship errors

hi i am using the following models to build a database
from django.db import models
from django.contrib import admin
class Team(models.Model):
"""Model docstring"""
slug = models.SlugField(max_length=200)
Team_ID = models.AutoField(primary_key=True)
Team_Name = models.CharField(max_length=100,)
College = models.CharField(max_length=100,)
College = models.CharField(max_length=1,)
Win = models.IntegerField()
Loss = models.IntegerField()
Draw = models.IntegerField()
class Match(models.Model):
Match_Id = models.AutoField(primary_key=True)
Team_one = models.ManyToManyField('Team',related_name='Team one',symmetrical=False,)
Team_two = models.ManyToManyField('Team',related_name='Team two',symmetrical=False,)
stadium = models.CharField(max_length=255, blank=True)
Start_time = models.DateTimeField(auto_now_add=False, auto_now=False, blank=True, null=True)
Rafree = models.CharField(max_length=255, blank=True)
Judge = models.CharField(max_length=255, blank=True)
winner = models.ForeignKey('Team', related_name='winner',to_field='Team_Name')
updated = models.DateTimeField('update date', auto_now=True )
created = models.DateTimeField('creation date', auto_now_add=True )
when i run the manage.py sqlall the model validate fine and gives me the sql output as follows
BEGIN;
CREATE TABLE "cupmanager_player" (
"slug" varchar(200) NOT NULL,
"Player_Id" serial NOT NULL PRIMARY KEY,
"Player_Name" varchar(100) NOT NULL,
"Nick" varchar(100) NOT NULL,
"Jersy_Number" integer NOT NULL,
"Team_id_id" integer NOT NULL,
"Poistion" varchar(1) NOT NULL,
"Red_card" integer NOT NULL,
"Yellow_card" integer NOT NULL,
"Points" integer NOT NULL
)
;
CREATE TABLE "cupmanager_team" (
"slug" varchar(200) NOT NULL,
"Team_ID" serial NOT NULL PRIMARY KEY,
"Team_Name" varchar(100) NOT NULL,
"College" varchar(1) NOT NULL,
"Win" integer NOT NULL,
"Loss" integer NOT NULL,
"Draw" integer NOT NULL
)
;
ALTER TABLE "cupmanager_player" ADD CONSTRAINT "Team_id_id_refs_Team_ID_1a532b57" FOREIGN KEY ("Team_id_id") REFERENCES "cupmanager_team" ("Team_ID") DEFERRABLE INITIALLY DEFERRED;
CREATE TABLE "cupmanager_match" (
"Match_Id" serial NOT NULL PRIMARY KEY,
"stadium" varchar(255) NOT NULL,
"Start_time" timestamp with time zone,
"Rafree" varchar(255) NOT NULL,
"Judge" varchar(255) NOT NULL,
"winner_id" varchar(100) NOT NULL REFERENCES "cupmanager_team" ("Team_Name") DEFERRABLE INITIALLY DEFERRED,
"updated" timestamp with time zone NOT NULL,
"created" timestamp with time zone NOT NULL
)
;
CREATE TABLE "cupmanager_goal" (
"Goal_ID" serial NOT NULL PRIMARY KEY,
"Match_ID_id" integer NOT NULL REFERENCES "cupmanager_match" ("Match_Id") DEFERRABLE INITIALLY DEFERRED,
"Team_ID_id" varchar(100) NOT NULL REFERENCES "cupmanager_team" ("Team_Name") DEFERRABLE INITIALLY DEFERRED,
"Player_ID_id" varchar(100) NOT NULL REFERENCES "cupmanager_player" ("Player_Name") DEFERRABLE INITIALLY DEFERRED,
"name" varchar(100) NOT NULL,
"updated" timestamp with time zone NOT NULL,
"created" timestamp with time zone NOT NULL
)
;
CREATE TABLE "cupmanager_match_Team_one" (
"id" serial NOT NULL PRIMARY KEY,
"match_id" integer NOT NULL REFERENCES "cupmanager_match" ("Match_Id") DEFERRABLE INITIALLY DEFERRED,
"team_id" integer NOT NULL REFERENCES "cupmanager_team" ("Team_ID") DEFERRABLE INITIALLY DEFERRED,
UNIQUE ("match_id", "team_id")
)
;
CREATE TABLE "cupmanager_match_Team_two" (
"id" serial NOT NULL PRIMARY KEY,
"match_id" integer NOT NULL REFERENCES "cupmanager_match" ("Match_Id") DEFERRABLE INITIALLY DEFERRED,
"team_id" integer NOT NULL REFERENCES "cupmanager_team" ("Team_ID") DEFERRABLE INITIALLY DEFERRED,
UNIQUE ("match_id", "team_id")
)
;
CREATE INDEX "cupmanager_player_slug" ON "cupmanager_player" ("slug");
CREATE INDEX "cupmanager_player_Team_id_id" ON "cupmanager_player" ("Team_id_id");
CREATE INDEX "cupmanager_team_slug" ON "cupmanager_team" ("slug");
CREATE INDEX "cupmanager_match_winner_id" ON "cupmanager_match" ("winner_id");
CREATE INDEX "cupmanager_goal_Match_ID_id" ON "cupmanager_goal" ("Match_ID_id");
CREATE INDEX "cupmanager_goal_Team_ID_id" ON "cupmanager_goal" ("Team_ID_id");
CREATE INDEX "cupmanager_goal_Player_ID_id" ON "cupmanager_goal" ("Player_ID_id");
COMMIT;
but when i now run the manage.py syncdb command i get the following error
psycopg2.ProgrammingError: there is no unique constraint matching given keys for referenced table "cupmanager_team"
any idea what is going on here ? i am using postgresql as the db backend and Postgresql_psycopg2 as the db back end
Mmh do you really have to use your own primary key fields? If you don't specify a primary key field, than Django automatically creates a field called id. I don't see a a benefit from naming the fields e.g. match_id, especially as you want to access this field later, it will look like match.match_id.
So maybe it works without your custom primary key fields.
Also not that the option symmetrical is only taken into account if the field is referencing self, i.e. the own table, which you are not doing here.

Categories

Resources