django south broke my db (can't drop constraint) - python

I wanted to add a table and a foreign key to that table. Initially I had:
class VirtualMachine(models.Model):
...
I then changed that to:
class OperatingSystem(models.Model):
name = models.CharField(max_length=40)
def __unicode__(self):
return self.name
class VirtualMachine(models.Model):
operating_system = models.ForeignKey(OperatingSystem, default=1)
and I wanted to make an entry so that 1 would be "WindowsXP". South didn't like that, though, so I changed the last line to:
operating_system = models.ForeignKey(OperatingSystem, null=True)
That worked ok. After that migration I added the "WindowsXP" entry and changed it back to:
operating_system = models.ForeignKey(OperatingSystem, default=1)
I did python manage.py schemamigration app --auto, which worked fine, then python manage.py migrate app, which froze. Froze!
I cancelled it and went into psql. I couldn't do SELECT * FROM app_virtualmachine; - that would hang, although getting stuff from other tables would not. I couldn't even select just a column from there. I tried dropping the constraint South added but also no good. What gives?

Ah I think the table got locked or something. I restarted postgres and then could do stuff manually to the table and rescue it.

Related

django states attibuteError although attribute is assigned

I have a Payment Django model that has a CheckNumber attribute that I seem to be facing issues with, at least whilst mentioning the attribute in the str method. It works just fine on the admin page when creating a Payment instance, but as soon as I called it in the method it gave me the following error message:
Request URL: http://127.0.0.1:8000/admin/Vendor/payment/
Django Version: 3.0.7
Exception Type: AttributeError
Exception Value:
'Payment' object has no attribute 'CheckNumber'
Exception Location: /Users/beepboop/PycharmProjects/novatory/Vendor/models.py in __str__, line 72
Python Executable: /Users/beepboop/Environments/novatory/bin/python3.7
Python Version: 3.7.2
this is my code:
class Payment(models.Model):
Vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
Amount = models.DecimalField(decimal_places=2, blank=True, max_digits=8)
PaymentDate = models.DateField(name="Payment date", help_text="Day of payment")
CheckNumber = models.IntegerField(name="Check number", help_text="If payment wasn't made with check, leave blank", blank=True)
def __str__(self):
return f"Vendor: {self.Vendor.Name} | Amount: {prettyPrintCurrency(self.Amount)} | Checknumber: {self.CheckNumber}"
I would absolutely love any comments/suggestions about the cause of the error
In my opinion, you have introduced CheckNumber field in the Payment models recently with no migration. make sure you run the migration then you can do that using the following command.
python manage.py migrate
This will create a new field in the Payment table. Hopefully, this will resolve your issue.
please clean the database and then run the migration command.
To clean the database you need to write the following command(Don't run this command in production):
python manage.py flush
After the cleaning, you can make an initial migration using the following command:
python manage.py makemigrations
and then migrate those changes to the database table:
python manage.py migrate
So it turns out that when you pass a name value in a model field, it changes the name of the field with it, I personally thought that it would change the name when displayed in the Django admin. My fix was to just remove the name value and migrate, that fixed it for me.

django: 'python manage.py migrate' taking hours (and other weird behavior)

I made some changes to one of my tables in models.py and tried migrating it with 'python manage.py migrate,' and it's taking hours. I only changed the names of three field (column) names, and it's been running for over 2 hours now. It ran smoothly (I think) in a matter of minutes when I created the table earlier this morning. Start of season is the model where changes were made.
Here is what from models.py looks like now:
from django.db import models
from django.contrib.gis.db import models as gismodels
# from django.contrib.gis import admin
# Create your models here.
class Location(models.Model): # table name automatically chirps_location
locationID = models.IntegerField(default=0, primary_key=True)
lat = models.FloatField(default=0.0)
lon = models.FloatField(default=0.0)
geom = gismodels.PointField(null=True)
objects = gismodels.GeoManager()
def __unicode__(self):
return u"LocationID: " + unicode(self.locationID)
# admin.site.unregister(Location)
# admin.site.register(Location, admin.OSMGeoAdmin)
class Rainfall(models.Model):
location = models.ForeignKey(Location)
year = models.IntegerField(default=0)
pentad_num = models.IntegerField(default=0)
pentad_val = models.FloatField(default=0.0)
class Meta:
ordering = ['location', 'year', 'pentad_num']
def __unicode__(self):
return u"LocationID: " + unicode(self.location.locationID) + u" Year: " + unicode(self.year) + u" Pentad: " + unicode(self.pentad_num)
class Start_of_Season(models.Model):
location = models.ForeignKey(Location)
crop = models.CharField(default='', max_length=40)
year = models.IntegerField(default=0)
first_rain = models.IntegerField(default=0)
onset_rain = models.IntegerField(default=0)
start_season = models.IntegerField(default=0)
class Meta:
ordering = ['location', 'crop', 'year']
def __unicode__(self):
return u"LocationID: " + unicode(self.location.locationID) + u" Year: " + unicode(self.year) + u" Start of Season pentad: " + unicode(self.start_season)
There was also some weird behavior that I couldn't explain going on before this, so I'll give a brief rundown of all of that too in case it's all related.
At first, my Start_of_Season class looked like this (notice the only difference is the names of the last 3 fields):
class Start_of_Season(models.Model):
location = models.ForeignKey(Location)
crop = models.CharField(default='', max_length=40)
year = models.IntegerField(default=0)
first_rain_pentad = models.IntegerField(default=0)
onset_rain_pentad = models.IntegerField(default=0)
start_season_pentad = models.IntegerField(default=0)
class Meta:
ordering = ['location', 'crop', 'year']
def __unicode__(self):
return u"LocationID: " + unicode(self.location.locationID) + u" Year: " + unicode(self.year) + u" Start of Season pentad: " + unicode(self.start_season)
Migrating it with:
python manage.py makemigrations
python manage.py migrate
appeared to run smoothly.
But when I ran a python script (excerpt) to add rows to this newly created Start_of_Season table:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "access.settings")
from chirps.models import Location, Rainfall, Start_of_Season
django.setup()
try:
with transaction.atomic():
for loc in Location.objects.all():
locID = loc.locationID
for yr in range(1981, 2014):
# some computations to find: c1, c2, c3
start_of_season = Start_of_Season()
start_of_season.location = Location.objects.get(locationID = locID)
start_of_season.crop = 'millet'
start_of_season.year = yr
start_of_season.first_rain_pentad = c1
start_of_season.onset_rain_pentad = c2
start_of_season.start_season_pentad = c3
start_of_season.save()
At first, the rows were never added to the database (according to psql at least). Then I got the error "start_of_season has no attribute start_season" which is weird because I never tried to access that attribute in my script, only "start_of_season.start_season_pentad"
So then I thought, okay, I'll change the names of the fields so that start_of_season does have that attribute. And that's when I edited models.py to look like the excerpt at the top of the post.
After updating updating models.py,
python manage.py makemigrations
ran with no errors:
(access_mw)mwooten#ip-10-159-67-226:~/dev/access$ python manage.py makemigrations
Did you rename start_of_season.first_rain_pentad to start_of_season.first_rain (a IntegerField)? [y/N] y
Did you rename start_of_season.onset_rain_pentad to start_of_season.onset_rain (a IntegerField)? [y/N] y
Did you rename start_of_season.start_season_pentad to start_of_season.start_season (a IntegerField)? [y/N] y
Migrations for 'chirps':
0010_auto_20150901_1454.py:
- Rename field first_rain_pentad on start_of_season to first_rain
- Rename field onset_rain_pentad on start_of_season to onset_rain
- Rename field start_season_pentad on start_of_season to start_season
, but:
python manage.py migrate
has been stuck here for hours:
(access_mw)mwooten#ip-10-159-67-226:~/dev/access$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, gis, djgeojson, messages, leaflet
Apply all migrations: admin, chirps, contenttypes, auth, sessions
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
Applying chirps.0010_auto_20150901_1454...
I don't see why this should take so long, seeing as how creating the actual table didn't. I'm also not sure why I was getting the other errors. Any ideas as to what's going on?
Thanks
More often than not this is because there is another SQL client or django server or shell reading/writing to the table that you are trying to modify.
An SQL command that changes a schema cannot be successfully executed while a table is being accessed. Ideally an error message should pop up but what usually happens is that the command just waits for the others to finish.
Once you close all your open shells, and sql clients, the schema change can happen. In the worst case, you might need to temporarily take the site offline too.
For me, it didn't even start! I used docker-compose to run my project and my Dockerfile contained RUN python manage.py migrate. Turned out that I put debugpy code in manage.py and let it wait for the debugger using wait_for_client without pressing debug button in vscode, which took forever.
As per debugpy documentation (Waiting for the client to attach)
Use the debugpy.wait_for_client() function to block program execution until the client is attached.
Here what I was trying to do: How to debug Django in VSCode with autoreload turned on

Django raw raises relation does not exist

i am getting a relation does not exist and I cant find a solution.
error:relation "sales_Oeslshstsql" does not exist
LINE 1: SELECT * FROM "sales_Oeslshstsql
(app name is sales)
model:
class Oeslshstsql(models.Model):
hst_prd = models.SmallIntegerField()
hst_year = models.SmallIntegerField()
cus_no = models.CharField(max_length=12)
item_no = models.CharField(max_length=15)
.....
a4glidentity = models.IntegerField(db_column='A4GLIdentity', primary_key = True)
class Meta:
managed = False
db_table = 'OESLSHST_SQL'
def __str__(self):
return (self.hst_year)
View:
def sales(request):
#sales_list = Oeslshstsql.objects.all().order_by('hst_year','hst_prd').reverse()
s = Oeslshstsql.objects.raw('SELECT * FROM "sales_Oeslshstsql"')
sales_list = s
return render(request,'saleslist.html',{'sales_list':sales_list})
The error is raised when s is evaluated. I tried switching cases in the select and messed with migrations no luck.
I am migrating an existing app to Django using a postgres backend, any help would be appreciated.
try:
s = Oeslshstsql.objects.raw('SELECT a4glidentity as id, ... , FROM "OESLSHST_SQL"')
http://docs.djangoproject.com/en/1.8/ref/models/options/#db-table seems your tablename in query is wrong
edit: you should add the primary key as id see https://docs.djangoproject.com/en/1.8/topics/db/sql/#mapping-query-fields-to-model-fields
Hi I had the same issue migrating an existing app to 1.11. The only solution I found was ....
Clear all all files from the app's migrations dir leaving only the init.py file
Make sure that the admin.py file is empty
Run manage.py makemigrations
Run manage.py sqlmigrate <app_label> 0001
copy the sql output
using pgAdminIII select "Execute arbitrary SQL queries"
Paste and execute the SQL statements in pgAdminIII
This was the only solution I could find, bit of a hack true, but worked. Hope it helps.This would also work via psql terminal I suppose, but I used pgAdmin

How to fix a Database Error and ghost migration error in Django?

I am getting an DatabaseError saying no column named playlist exists and I'm trying to figure out how to fix it. I'm using South. I deleted the old files in the my migrations folder and ran:
python manage.py schemamigration app_name --initial
python manage.py migrate reserve
I get this error when I do that:
south.exceptions.GhostMigrations:
! These migrations are in the database but not on disk:
<reserve: 0002_initial>
! I'm not trusting myself; either fix this yourself by fiddling
! with the south_migrationhistory table, or pass --delete-ghost-migrations
! to South to have it delete ALL of these records (this may not be good).
I'm not sure how to get rid of this error, since in my migrations folder I only have init.py(c) and 0001_initial.py(c); I don't have 0002 migration file anymore.
When I try runserver and click "add playlist" in the admin, this is when I get the DatabaseError. If it helps, my models.py is:
class UserProfile(models.Model):
user = models.OneToOneField(User)
def __unicode__(self):
return self.user
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
class Playlist(models.Model):
playlist = models.CharField('Playlist', max_length = 2000, null=True, blank=True)
def __unicode__(self):
return self.playlist
class Video(models.Model):
video_url = models.URLField('Link to video', max_length = 200, null=True, blank=True)
def __unicode__(self):
return self.video_url
class UserPlaylist(models.Model):
profile = models.ForeignKey(User)
playlist = models.ForeignKey(Playlist)
def __unicode__(self):
return self.playlist
class Videoplaylist(models.Model):
video = models.ForeignKey(Video)
playlist = models.ForeignKey(UserPlaylist)
def __unicode__(self):
return self.playlist
Any advice on how to fix this?
Just run
python manage.py migrate reserve --delete-ghost-migrations
This should remove non existing migration from the database table south_migrationhistory.
First, you should work out what happened to get the db and filesystem out of sync.
Then, if appropriate, you can do
python manage.py migrate reserve --ignore-ghost-migrations
or
python manage.py migrate reserve --delete-ghost-migrations
as Aidas said, whichever seems more appropriate. The ignore option is probably less risky, although something has already gone astray for you to get to this state.
South stores migration information in the database too, in a table called "migrations". [ I think thats the table name; writing this from memory ].
You need to clear that table out.
Note
Once you clear that table out, you have to start the migrations again from scratch; right from the initial migration.
It would be a good idea to make a copy of your database as-is before you do this. I assume that your code is already version controlled.
Usually this error happens because, you created a migration file and did the migration then, that migration file was deleted from your file system(disk)
So you have changes in your database caused by a migration that no longer exists.
Depending on whether you deleted the migration file file by choice, what you can do; is go ahead and also delete the changes from the database.
Start the python shell;
$ python manage.py shell
>>from south.models import MigrationHistory
>>MigrationHistory.objects.filter(migration='0002_initial').delete()
That will have deleted the 0002 migration from the db.
You can now go ahead and create/recreate the migration you want.
Goodluck,
Komu.
Just run the command where manage.py file is present in your directory
./manage.py migrate appname --delete-ghost-migrations

django south is changing my boolean data on init

To output my database to json file I would usually do
python manage.py dumptdata --indent=4 > mydata.json
However upon executing the following two commands to setup south:
python manage.py schemamigration myproj --initial
python manage.py migrate myproj --fake
I noticed that two of my booleans in mytable for an entry were switched from FALSE to TRUE! I see that from my GUI Web Interface interacting with the database however to more closely compare what changed and got corrupted I'd like to compare json to json but with south enabled I can no longer use the above command as it tells me
Not synced (use migrations):
- myproj
My table that had entries affected is below, I could have more affected data that I have not uncovered.
class MyConfig(models.Model):
name = models.CharField(max_length=64)
myConfigName = models.CharField(max_length=64, unique=True)
myA = models.ForeignKey(MyA)
myB = models.ForeignKey(MyB)
myBoolA = models.BooleanField()
myBoolB = models.BooleanField()
myBoolC = models.BooleanField()
class Meta:
unique_together = ('name', 'myA', 'myB')
def __unicode__(self):
return '%s_%s_%s' % (self.myA.name, self.myB.name, self.name)
schemamigration and migrate --fake don't modify the database. Do you have any initial_data fixture that could be reloaded when migrating? See https://docs.djangoproject.com/en/1.3/howto/initial-data/
Try to migrate with:
python manage.py migrate --no-initial-data
see south doc for more info about options
I don't think that either an --initial or a --fake should alter the database at all, so I'm surprised that it would modify data. In terms of why you're getting the "Not synced (use migrations)" error, I think it's likely because you faked the initial migration.
Try un-migrating the --fake and re-applying the initial migration with
python manage.py migrate --fake zero
python manage.py migrate
Then, you should be able to do the dumptdata

Categories

Resources