django database many2many relationship errors - python

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.

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 ?

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?

How to fix error: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint?

Why is the error below occurring? I am aware of the db.session.add() method however I want to use raw SQL for learning sake. Shouldn't the UUID be auto-generating? Maybe I am missing something in the postgresql text or have the id not correct in the model?
error
Error: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, testuser, email#test.com, pASsWorD, null, 2021-01-10 16:13:23.270353-08).
models.py
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import DateTime
from sqlalchemy.sql import func
from .. import db
class Users(db.Model):
__tablename__ = 'users'
id = db.Column(
UUID(as_uuid=True),
primary_key=True,
unique=True,
)
username = db.Column(
db.String(120),
unique=True,
nullable=False
)
email = db.Column(
db.String(120),
unique=True,
nullable=False
)
password = db.Column(
db.String(120),
nullable=False
)
updated_at = db.Column(
DateTime(timezone=True),
onupdate=func.now()
)
created_at = db.Column(
DateTime(timezone=True),
server_default=func.now()
)
api.py
from flask import Blueprint, request, jsonify
from sqlalchemy import text, exc
from types import SimpleNamespace
from ...models.users import db, Users
bp = Blueprint('api', __name__, url_prefix='/api/v1')
#bp.route('/users', methods=['POST'])
def users():
if request.method == 'POST':
try:
response = dict(request.get_json())
values = SimpleNamespace(**response)
if all(response.values()):
sql_insert_one = text(f"INSERT INTO users(username, email, password) VALUES ('{values.username}', '{values.email}', '{values.password}');")
db.session.execute(sql_insert_one)
db.session.commit()
message = f"successfully added new user: {values.username}"
else:
message = f"error adding new user, values submitted: {values}"
return jsonify(response)
except Exception as err:
print(f'Error: {err}')
return jsonify(f'"error":"{err}"')
To answer your question "shouldn't the UUID be auto-generating?" No. From the postgresql docs: 'the core database does not include any function for generating UUIDs' ref.
You need to generate the UUID yourself, try uuid.
Or you can use db.Integer instead of db.UUID and SQLAlchemy will make it a sequence and it will auto-generate the id value.
In My case, everything is fine from the code level. But when I cross-checks the table DDL query(Structure), Autoincrement is not available in table level.
CREATE TABLE public.example_table (
id int4 NOT NULL,
table_name varchar(100) NULL,
created_at timestamptz(6) NOT NULL,
created_by_id int4 NULL,
CONSTRAINT "example_table_pkey" PRIMARY KEY (id)
);
It should be
CREATE TABLE public.example_table (
id serial NOT NULL,
table_name varchar(100) NULL,
created_at timestamptz(6) NOT NULL,
created_by_id int4 NULL,
CONSTRAINT "example_table_pkey" PRIMARY KEY (id)
);
Make sure your table structure.
It may helpful for someone

Django Foreign key constraint error on submitting a row

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

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')

Categories

Resources