In Django (2.x) I have an entry form, the model is here:
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class Sample(models.Model):
sample_id = models.AutoField(primary_key=True)
area_easting = models.IntegerField()
area_northing = models.IntegerField()
context_number = models.IntegerField()
sample_number = models.IntegerField()
# taken_by = models.IntegerField()
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.PROTECT)
def __str__(self):
return str(self.sample_id)
class Meta:
db_table = 'samples\".\"sample'
#ordering = ["sample_id"]
managed = False
#verbose_name_plural = "samples"
This works as expected, a list of usernames drops down (while I would like to format - firstname lastname). However, when I return to the main viewing page I see an error.
django.db.utils.ProgrammingError: column sample.taken_by_id does not exist
LINE 1: ...text_number", "samples"."sample"."sample_number", "samples"....
^
HINT: Perhaps you meant to reference the column "sample.taken_by".
Clearly Django is adding the _id to the table name causing the error, I expect because it is a foreign key.
Any ideas how to remedy this behaviour?
You can explicitly set the underlying db column via the db_column attribute:
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column='taken_by', on_delete=models.PROTECT)
https://docs.djangoproject.com/en/2.1/ref/models/fields/#database-representation
^ link to the docs where it specifies that it creates a _id field.
based from the error message you have posted. It seems that your database schema is not updated.
you might need to do manage makemigrations and migrate to apply your model changes to your db schema
e.g
$ python manage.py makemigrations
# to apply the new migrations file
$ python manage.py migrate
I created the following models in my app events :
from django.db import models
from django.utils import timezone
from django.urls import reverse
class EventType(models.Model):
type_of_event = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.type_of_event
class Event(models.Model):
type_of_event = models.ForeignKey(EventType, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.TextField()
event_date = models.DateTimeField(default=timezone.now())
venue = models.CharField(max_length=200)
entry_fee = models.FloatField()
def __str__(self):
return self.name
Due to some errors and changes, I created and deleted the migration file many times. Now, the makemigrations command works but when I try to migrate the models using : python manage.py migrate , it shows the following error:
File "/home/anirudh/.local/share/virtualenvs/Amrita-event-manager-DHqKHtGE/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 294, in execute
return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: table "events_event" already exists
I am using django version 2.1 along with sqlite3.
Most questions similar to this were too old and incompatible to the version I am using now.
First of all, make a backup of the file db.sqlite3
You could use dbshell, which runs the command-line client for the database engine
https://docs.djangoproject.com/en/dev/ref/django-admin/#django-admin-dbshell
python manage.py dbshell
list all tables
sqlite> .table
delete table
sqlite> DROP TABLE <table>;
I am using Django ; and when I change a model , getting an error everytime .
I am changing only one field in model, and getting stupidly a lot of errors EVERYTIME.
django.db.utils.OperationalError: no such table:
or
django.db.migrations.exceptions.InconsistentMigrationHistory:
or
OperationalError no such column: table.colunm
or
django.db.utils.OperationalError: "Table already exists"
and bla bla bla..
I got maybe all error types in Django , and now it is bothering me really.
I am trying all solutions everytime :
Delete migrations
find . -path "/migrations/.py" -not -name "init.py" -delete
find . -path "/migrations/.pyc" -delete
Clear the migration history for each app
Remove the actual migration files.
Create the initial migrations
Fake the initial migration
python manage.py migrate --fake
python manage.py migrate --fake-initial
python manage.py migrate --run-syncdb
Drop database
Every solutions what i can find.
Stupidly trying all the solutions , and; at the last , yes i can find solutions BUT , I really really bored now from this stupidly errors.
Is there any way to get rid of migration errors in Django ?
Only I need the answer for this ; 'When I change a model field only, why am I getting these all madly errors, EVERYTIME ??!!!?'
For example :
this is my model :
from django.db import models
from django.conf import settings
from etahfiz.sabitler import DERS_SEVIYESI
# Create your models here.
class Student(models.Model):
systemId = models.CharField(max_length=15, unique=True )
adSoyad = models.CharField(max_length=20, blank=True)
dersSeviyesi = models.CharField(max_length=15,choices=DERS_SEVIYESI )
def __str__(self):
return str(self.systemId)
class Teacher(models.Model):
systemId = models.CharField(max_length=15 , unique=True)
user = models.OneToOneField(settings.AUTH_USER_MODEL)
adSoyad = models.CharField(max_length=20, blank=True)
def __str__(self):
return str(self.systemId)
class StuTeach(models.Model):
student = models.ForeignKey(Talebe)
teacher = models.ForeignKey(Hoca)
tarihBas = models.DateField()
tarihBit = models.DateField(blank=True, null=True)
This was working perfectly , BUT ; I wanted to add only one field to Teacher Model :
dersSeviyesi = models.CharField(max_length=15,choices=DERS_SEVIYESI )
Teacher model is like this now :
class Teacher(models.Model):
systemId = models.CharField(max_length=15 , unique=True)
user = models.OneToOneField(settings.AUTH_USER_MODEL)
adSoyad = models.CharField(max_length=20, blank=True)
dersSeviyesi = models.CharField(max_length=15,choices=DERS_SEVIYESI )
def __str__(self):
return str(self.systemId)
Aannd when I try to migrate :
python manage.py makemigrations sinif
python manage.py migrate
error error error
django.db.utils.OperationalError: "Table already exists"
Or sth like that..
Everytime that change only one field, getting all errors of Django...
How can I get rid of this type errors ??
Thank you.
Go to your database and find migrations table and also delete on entries. Then run migrations again. At this time you may face ContentType already exists. THen delete content_type table. Or, the easiest solution is to delete the database and create again, but if you have important data, all data will be lost.
I have below model:
class Property(models.Model):
job = models.ForeignKey(Job, on_delete=models.CASCADE)
app = models.ForeignKey(App, on_delete=models.CASCADE)
name = models.CharField(max_length=120)
value = models.CharField(max_length=350, blank=True)
description = models.TextField(blank=True)
pub_date = models.DateTimeField('date_published', default=timezone.now)
class Meta:
verbose_name_plural = "properties"
unique_together = (('value', 'name'),)
def __str__(self):
return self.name
When I try to create a Property object in admin page (I'm using Django Suit) with name/value which are already exist I get the exception: "Property with this Value and Name already exists." So it works perfect.
But in manage.py shell:
>>>from myapp.models import App, Property, Job
>>>from django.shortcuts import get_object_or_404
>>>app = get_object_or_404(App, app_name='BLABLA')
>>>job = get_object_or_404(Job, job_name='BLABLA2')
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
In this case I do not get any exceptions and objects are added in database.
I tried makemigrations, migrate and migrate --run-syncdb.
Django 1.9.12, sqlite3
The unique constraints are enforced at database level. You're not getting any error probably because SQLite doesn't support this type of constraint. You cannot add constraint to existing table in SQLite. If you're in early development stage, drop the table and recreate it with updated constraints. Then it should work fine in shell.
Check SQLite alter table docs for allowed updates on an existing table.
The admin form throws error because it checks uniqueness by itself without relying on database constraints.
I'm trying to modify a M2M field to a ForeignKey field. The command validate shows me no issues and when I run syncdb :
ValueError: Cannot alter field xxx into yyy they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)
So I can't make the migration.
class InstituteStaff(Person):
user = models.OneToOneField(User, blank=True, null=True)
investigation_area = models.ManyToManyField(InvestigationArea, blank=True,)
investigation_group = models.ManyToManyField(InvestigationGroup, blank=True)
council_group = models.ForeignKey(CouncilGroup, null=True, blank=True)
#profiles = models.ManyToManyField(Profiles, null = True, blank = True)
profiles = models.ForeignKey(Profiles, null = True, blank = True)
Any suggestions?
I stumbled upon this and although I didn't care about my data much, I still didn't want to delete the whole DB. So I opened the migration file and changed the AlterField() command to a RemoveField() and an AddField() command that worked well. I lost my data on the specific field, but nothing else.
I.e.
migrations.AlterField(
model_name='player',
name='teams',
field=models.ManyToManyField(related_name='players', through='players.TeamPlayer', to='players.Team'),
),
to
migrations.RemoveField(
model_name='player',
name='teams',
),
migrations.AddField(
model_name='player',
name='teams',
field=models.ManyToManyField(related_name='players', through='players.TeamPlayer', to='players.Team'),
),
NO DATA LOSS EXAMPLE
I would say: If machine cannot do something for us, then let's help it!
Because the problem that OP put here can have multiple mutations, I will try to explain how to struggle with that kind of problem in a simple way.
Let's assume we have a model (in the app called users) like this:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person)
def __str__(self):
return self.name
but after some while we need to add a date of a member join. So we want this:
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership') # <-- through model
def __str__(self):
return self.name
# and through Model itself
class Membership(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
Now, normally you will hit the same problem as OP wrote. To solve it, follow these steps:
start from this point:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person)
def __str__(self):
return self.name
create through model and run python manage.py makemigrations (but don't put through property in the Group.members field yet):
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=128)
def __str__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person) # <-- no through property yet!
def __str__(self):
return self.name
class Membership(models.Model): # <--- through model
person = models.ForeignKey(Person, on_delete=models.CASCADE)
group = models.ForeignKey(Group, on_delete=models.CASCADE)
date_joined = models.DateField()
create an empty migration using python manage.py makemigrations users --empty command and create conversion script in python (more about the python migrations here) which creates new relations (Membership) for an old field (Group.members). It could look like this:
# Generated by Django A.B on YYYY-MM-DD HH:MM
import datetime
from django.db import migrations
def create_through_relations(apps, schema_editor):
Group = apps.get_model('users', 'Group')
Membership = apps.get_model('users', 'Membership')
for group in Group.objects.all():
for member in group.members.all():
Membership(
person=member,
group=group,
date_joined=datetime.date.today()
).save()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0005_create_models'),
]
operations = [
migrations.RunPython(create_through_relations, reverse_code=migrations.RunPython.noop),
]
remove members field in the Group model and run python manage.py makemigrations, so our Group will look like this:
class Group(models.Model):
name = models.CharField(max_length=128)
add members field the the Group model, but now with through property and run python manage.py makemigrations:
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
and that's it!
Now you need to change creation of members in a new way in your code - by through model. More about here.
You can also optionally tidy it up, by squashing these migrations.
Potential workarounds:
Create a new field with the ForeignKey relationship called profiles1 and DO NOT modify profiles. Make and run the migration. You might need a related_name parameter to prevent conflicts. Do a subsequent migration that drops the original field. Then do another migration that renames profiles1 back to profiles. Obviously, you won't have data in the new ForeignKey field.
Write a custom migration: https://docs.djangoproject.com/en/1.7/ref/migration-operations/
You might want to use makemigration and migration rather than syncdb.
Does your InstituteStaff have data that you want to retain?
If you're still developing the application, and don't need to preserve your existing data, you can get around this issue by doing the following:
Delete and re-create the db.
go to your project/app/migrations folder
Delete everything in that folder with the exception of the init.py file. Make sure you also delete the pycache dir.
Run syncdb, makemigrations, and migrate.
Another approach that worked for me:
Delete the existing M2M field and run migrations.
Add the FK field and run migrations again.
FK field added in this case has no relation to the previously used M2M field and hence should not create any problems.
This link helps you resolve all problems related to this
The one which worked for me is python3 backend/manage.py migrate --fake "app_name"
I literally had the same error for days and i had tried everything i saw here but still didn'y work.
This is what worked for me:
I deleted all the files in migrations folder exceps init.py
I also deleted my database in my case it was the preinstalled db.sqlite3
After this, i wrote my models from the scratch, although i didn't change anything but i did write it again.
Apply migrations then on the models and this time it worked and no errors.
This worked for Me as well
Delete last migrations
run command python manage.py migrate --fake <application name>
run command 'python manage.py makemigrations '
run command 'python manage.py migrate'
Hope this will solve your problem with deleting database/migrations
First delete the migrations in your app (the folders/ files under 'migrations'
folder)
Showing the 'migrations' folder
Then delete the 'db.sqlite3' file
Showing the 'db.sqlite3' file
And run python manage.py makemigrations name_of_app
Finally run python manage.py migrate
I had the same problem and found this How to Migrate a ‘through’ to a many to many relation in Django article which is really really helped me to solve this problem. Please have a look. I'll summarize his answer here,
There is three model and one(CollectionProduct) is going to connect as many-to-many relationship.
This is the final output,
class Product(models.Model):
pass
class Collection(models.Model):
products = models.ManyToManyField(
Product,
blank=True,
related_name="collections",
through="CollectionProduct",
through_fields=["collection", "product"],
)
class CollectionProduct(models.Model):
collection = models.ForeignKey(Collection, on_delete=models.CASCADE)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
class Meta:
db_table = "product_collection_products"
and here is the solution,
The solution
Take your app label (the package name, e.g. ‘product’) and your M2M field name, and combine them together with and underscore:
APPLABEL + _ + M2M TABLE NAME + _ + M2M FIELD NAME
For example in our case, it’s this:
product_collection_products
This is your M2M’s through database table name. Now you need to edit your M2M’s through model to this:
Also found another solution in In Django you cannot add or remove through= on M2M fields article which is going to edit migration files. I didn't try this, but have a look if you don't have any other solution.
this happens when adding 'through' attribute to an existing M2M field:
as M2M fields are by default handled by model they are defined in (if through is set).
although when through is set to new model the M2M field is handled by that new model, hence the error in alter
solutions:-
you can reset db or
remove those m2m fields and run migration as explained above then create them again
*IF YOU ARE IN THE INITIAL STAGES OF DEVELOPMENT AND CAN AFFORD TO LOOSE DATA :)
delete all the migration files except init.py
then apply the migrations.
python manage.py makemigrations
python manage.py migrate
this will create new tables.