django.db.utils.IntegrityError(could not create unique index) - django-models

When am trying to add new Unique_id (uuid) field in the existing django models , It returns the intgerity error.
models.py:
class Directory(models.Model):
unique_id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
name = models.CharField(max_length=120)
path = models.CharField(max_length=240)
Views.py:
def get_dir_dict(request, dir):
dir_info['pk'] = query.pk
dir_info['unique_id'] = query.unique_id
dir_info['name'] = query.name
dir_info['path'] = query.path
error:
File "/home/sitharth/zeal/lib64/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: could not create unique index "zkloud_directory_unique_id_key"
DETAIL: Key (unique_id)=(734e8926-386b-47a9-9ac0-d617f45f7113) is duplicated.

Related

Flask SQLAlchemy 2 ForeignKey columns going back to the same table

I have a Users table and a Tasks table. The Tasks table has an "author" column and an "assignee" column, both of which are foreign keys to the unique ID in Users.
As you might expect, this produced an error: "Could not determine join condition between parent/child tables on relationship Users.created_tasks - there are multiple foreign key paths linking the tables."
What's another way to record both the "author" and "assignee" if I wanted to have both columns in the table?
class Tasks(db.Model):
// ...
author = db.Column(db.Integer, db.ForeignKey('users.id'))
assignee = db.Column(db.Integer, db.ForeignKey('users.id'))
class Users(db.Model, UserMixin):
// ...
created_tasks = db.relationship('Tasks', backref = 'ctasks_user')
assigned_tasks = db.relationship('Tasks', backref = 'atasks_user')
You can specify the primaryjoin attribute of each relationship to differentiate the two:
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
connection_uri = (
"mssql+pyodbc://#localhost:49242/myDb?driver=ODBC+Driver+17+for+SQL+Server"
)
engine = sa.create_engine(connection_uri)
with engine.begin() as conn:
conn.execute(sa.text("DROP TABLE IF EXISTS task_t"))
conn.execute(sa.text("DROP TABLE IF EXISTS user_t"))
Base = declarative_base()
class Task(Base):
__tablename__ = "task_t"
id = sa.Column(sa.Integer, primary_key=True)
description = sa.Column(sa.String(50))
author = sa.Column(sa.Integer, sa.ForeignKey("user_t.id"))
assignee = sa.Column(sa.Integer, sa.ForeignKey("user_t.id"))
def __repr__(self):
return f"<Task(id={self.id}, description='{self.description}')>"
class User(Base):
__tablename__ = "user_t"
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(50))
created_tasks = relationship(
Task,
primaryjoin="User.id == Task.author",
backref="user_created_tasks",
)
assigned_tasks = relationship(
Task,
primaryjoin="User.id == Task.assignee",
backref="user_assigned_tasks",
)
def __repr__(self):
return f"<User(id={self.id}, name='{self.name}')>"
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
homer = User(name="Homer")
bart = User(name="Bart")
lisa = User(name="Lisa")
session.add_all([homer, bart, lisa])
session.commit()
mow_the_lawn = Task(
description="Mow the lawn", author=homer.id, assignee=bart.id
)
wash_the_car = Task(
description="Wash the car", author=homer.id, assignee=lisa.id
)
session.add_all([mow_the_lawn, wash_the_car])
session.commit()
with engine.begin() as conn:
result = conn.execute(
sa.text("SELECT * FROM user_t ORDER BY id")
).fetchall()
print(result)
# [(1, 'Homer'), (2, 'Bart'), (3, 'Lisa')]
result = conn.execute(
sa.text("SELECT * FROM task_t ORDER BY id")
).fetchall()
print(result)
# [(1, 'Mow the lawn', 1, 2), (2, 'Wash the car', 1, 3)]
print(homer.created_tasks)
# [ <Task(id=1, description='Mow the lawn')>, <Task(id=2, description='Wash the car')>]
print(bart.assigned_tasks)
# [ <Task(id=1, description='Mow the lawn')>]

how to solve the slugfield int () problem

slugfield does not work the problem is invalid literal for int() with base 10:
I try all English video and some French video
models
from django.utils.text import slugify
class Region(models.Model):
...
slug = models.SlugField(max_length=140, unique=True)
def __str__(self):
return self.name
def _get_unique_slug(self):
slug = slugify(self.name)
unique_slug = slug
num = 1
while Region.objects.filter(slug=unique_slug).exists():
unique_slug = '{}-{}'.format(slug, num)
num += 1
return unique_slug
def save(self, *args, **kwargs):
if not self.slug:
self.slug = self._get_unique_slug()
super().save(*args, **kwargs)
urls
path('<region_slug>', views.detail, name='detail'),
views
def detail(request,region_slug):
region=get_object_or_404(Region ,pk=region_slug)
context = {
.....
'region_slug':region.slug
}
I think your problem is in your view. This line points to the primary key (pk) of your model, but the pk isn't the same as the slug. The pk is referencing the auto-inserted id field.
def detail(request, region_slug):
region = get_object_or_404(Region, pk=region_slug)
You could make the slug field your primary key, but I would suggest rather pointing to the slug field as it stands now.
def detail(request, region_slug):
region = get_object_or_404(Region, slug=region_slug)

ValueError: variable needs to have a value for field "id" before this many to many relationship can be used - Django

I created a datamodel in Django, and now I created a script to auto populate the models using web-scraped values. However when I run the script I get the following error:
ValueError: variable needs to have a value for field "id" before this many to many relationship can be used
Models.py
class Books(models.Model):
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Meta:
ordering = ['-title']
class Author(models.Model):
book = models.ManyToManyField(Books)
first_name = models.CharField(max_length=150)
last_name = models.CharField(max_length=200)
def __str__(self):
return "{} {}".format(self.first_name, self.last_name)
class Meta:
ordering = ['last_name','first_name']
class Book_details(models.Model):
book = models.ForeignKey(Books,
on_delete=models.CASCADE,
null=True) # models.SET_NULL weggehaald
pages = models.CharField(max_length=250)
publ_year = models.CharField(max_length=250)
edition = models.CharField(max_length=30) # paperback, hardcover, audiobook, etc
def __str__(self):
return "{} - pages: <{}>, edition: <{}>".format(self.book.title,
self.pages,
self.edition)#
class Cover(models.Model):
book = models.OneToOneField(Books,
on_delete=models.CASCADE)
path = models.CharField(max_length=500)
def __str__(self):
return "<Cover <path={}>".format(self.id, self.path)
populate_script
def add_book(title):
b = Books.objects.get_or_create(title = title)[0]
print(b)
b.save()
return b
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_name = b_author_last)[0]
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]
The scraped_tuple is a return value from the webscraper containing the details.
(Part of) the Traceback:
Books.models.DoesNotExist: Author matching query does not exist.
File "C:\path\to\LibraryApp\Library_WebA
pp\Library\populate.py", line 45, in populate
new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_nam
e = b_author_last)[0]
Followed by:
ValueError: "<Author: Mary McCarthy>" needs to have a value for field "id" before this many-to-many relationship can be used.
So, it seems that something goes awfully wrong when trying to execute the new_author statement, because of the many-to-many field "book" in the Author model. How can I resolve this. Do I need a similar function for an Author object like I have for the Book in add_book()?
It seems the new_details statement executes just fine (title and book_details appear correctly in the database in the admin part of Django).
As mentioned in the docs, user .add() to associate the records in many to many field.
def populate(scraped_tuple):
fake = Faker()
for _ in range(len(scraped_tuple)):
b_title = scraped_tuple[_][0][0]
new_book = add_book(b_title)
b_author_first = scraped_tuple[_][0][1].split(" ")[0]
b_author_last = scraped_tuple[_][0][1].split(" ")[1]
b_pages = scraped_tuple[_][0][2].split(" ")[0]
b_publ_year = fake.year()
b_edition = scraped_tuple[_][0][3].split(",")[0]
b_cover = scraped_tuple[_][0][4]
new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]
new_author = Author.objects.get_or_create(first_name = b_author_first, last_name = b_author_last)[0]
# add many to many fields this way:
new_author.book.add(new_book)
new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]

Flask model return all table columns

i have this on my model
class Social(db.Model):
__tablename__ = 'social_auth_usersocialauth'
id = db.Column('id',db.Integer, primary_key=True)
provider = db.Column('provider',db.String(32))
extra_data = db.Column('extra_data',db.String())
uid = db.Column('uid',db.String(255))
def __init__(self,id, provider, extra_data, uid):
self.id = id
self.provider = provider
self.extra_data = extra_data
self.uid = uid
def __repr__(self):
return self.uid
and when i call it to my view, i just get the uid, yes i know because in my model i just returned it's uid, the question is, how can i return all of it's table's columns ?
like id, provider, also extra_data column,,,
Thank you.
The simpler way is to comment your repr function and return the Social object and use it's attributes by calling
social = Social.query.first() # example
id = social.id
providor = object.providor
...
But if you really want to do it this way you can return all attributes in repr by:
def __repr__(self):
return self.id, self.providor, self.extra_data, self.uid
and changing this in you views to this and get all values by::
id, providor, extra_data, uid = Social.query.first() # example

Function does't add data to model(via serializer)

Here is function I wrote, it checks field called 'url' inside 'Url1' Model and continues IF it's empty.
def mozs():
getids = Url1.objects.values_list('id', flat=True)
for id in getids:
if Url1.objects.get(id=id).pda == None:
authorities= {"pda": 58.26193857945012, "upa": 36.56733779379807}
authorities['keyword'] = id
serializer = MozSerializer(data=authorities)
if serializer.is_valid():
serializer.save()
print "For %d we added %s" % (id, authorities)
Here is output:
For 37 we added {'keyword': 37, 'pda': 58.26193857945012, 'upa': 36.56733779379807}
But it doesn't add it. Here is serializer:
class MozSerializer(serializers.Serializer):
keyword = serializers.PrimaryKeyRelatedField(queryset=KW.objects.all())
pda = serializers.FloatField()
upa = serializers.FloatField()
def save(self):
keyword = self.validated_data['keyword']
pda = self.validated_data['pda']
upa = self.validated_data['upa']
Url1.objects.update(pda=pda, upa=upa)

Resources