Migrating django sqlite database to postgresql - python

I've been trying for a long while to migrate the sqlite database to a more stable postgresql since I am going into production. I've had some problems, but the one I've hit a roadblock and can't get any further.
To get the backup I ran ./manage.py dumpdata --exclude auth.permission --exclude contenttypes --natural-foreign > db.json with sqlite configured in settings.py.
Once the postgresql database was configured I ran a ./manage.py migrate with postgresql configured in settings.py.
Finally I ran ./manage.py loaddata db.json and got the following error:
django.db.utils.ProgrammingError: Problem installing fixture '/home/ubuntu/bl/loom/db.json': Could not load web.Project(pk=18): operator does not exist: character varying = integer
LINE 1: ...INNER JOIN "web_project_tags" ON ("web_tag"."tag" = "web_pro...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
The model(s) that the error is referring to has the following code:
class Project(models.Model):
owner = models.ForeignKey(User, related_name='owner')
name = models.CharField(max_length=50)
img = models.ImageField("Cover", upload_to="img/projects", blank=True, null=True)
vid = models.URLField("Youtube Link", null=True, blank=True)
desc = models.TextField("Description", max_length=500)
stakeholders = models.ManyToManyField(Profile, related_name='stakeholders', blank=True)
industry = models.ManyToManyField(Industry, related_name="industry")
tags = models.ManyToManyField(Tag, related_name="project_tag")
is_private = models.BooleanField("Is this a private project?", default=False, help_text="Private projects are not shown on the index.")
b_type = models.ForeignKey(B_type, help_text="What type of project is this")
role = models.ForeignKey(Role, related_name="role")
deleted = models.BooleanField(default=False)
def __unicode__(self):
return self.name
class Meta:
verbose_name = "Project"
verbose_name_plural = "Projects"
class Tag(models.Model):
tag = models.CharField("Tag", max_length=100, primary_key =True)
def __unicode__(self):
return self.tag
class Meta:
verbose_name = "Tag"
verbose_name_plural = "Tags"
Update:
The log file contains a more detailed error and it shows the full query.
2016-05-09 00:54:39 UTC ERROR: operator does not exist:
character varying = integer at character 89
2016-05-09 00:54:39 UTC HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
2016-05-09 00:54:39 UTC STATEMENT: SELECT "web_tag"."tag" FROM "web_tag" INNER JOIN "web_project_tags" ON ("web_tag"."tag" = "web_project_tags"."tag_id") WHERE "web_project_tags"."project_id" = 18

I finally solved the problem, hopefully this answer will help someone.
After checking the log I checked the postgresql database for the tables it was throwing an error. It turns out that web_project_tags had the wrong data type even though the migrations were done to the latest version. I corrected this data type using:
ALTER TABLE problematic_table ALTER COLUMN problematic_column TYPE character varying(100);
With this I ended up loading the data with ./manage.py loaddata db.jsonand no more errors.

Related

django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table

I am having a problem with Django 2.2.7 and postgresql 12 using the command "python manage.py migrate".
When I execute it, the process fails with the following error:
django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "clients_clients"
I understand that this error indicates that when a field is used as a foreing key in another table, this field must be unique.
My model clients in Django is:
class Clients(models.Model):
name = models.CharField(max_length=60, unique=True)
document_num = models.CharField(max_length=15)
phone = models.CharField(max_length=15, blank=True)
email = models.EmailField(max_length=30, blank=True)
instagram = models.CharField(max_length=30, blank=True)
address = models.TextField(max_length=100, blank=True)
The model with the foreing key to the field "name" of clients_clients is:
class Budgets(models.Model):
date = models.DateField(error_messages={'null': "You must set a date"})
title = models.CharField(max_length=50, unique=True)
client = models.ForeignKey(Clients, null=True, on_delete=models.SET_NULL, to_field='name')
price = models.DecimalField(default=0, decimal_places=2, max_digits=10)
observations = models.TextField(max_length=200, blank=True)
As is shown above, the field "name" in model "Clients" is set as unique=True. But in spite of that, the error mentioned is shown.
Anyone can help me to understand why?
I could fix the problem.
The problem is as I copied my Django application from an existing installation to a new one, a lot of migration files exist in the app folders.
First, I had to delete all the files inside the "migrations" folders in any app of my Django project (taking care of not delete the init.py file).
Then I ran again the commands:
python manage.py makemigrations
and
python manage.py migrate
Now, everything works fine.

Python Django OperationalError no such column model.id

When trying to access my model via the Admin webpage using Django, I get an Operational Error stating "no such column: model_name.id"
I did my migrations and all but I am still getting the same error.
I assume I am getting this error because I had to change the name of my model. Since, I had to delete my database and migrations and had to re migrate all of my changes.
I originally got the error of not having a table built so I used some SQL to build the table and now I am stuck with a missing column under the name "id". Thanks in advance.
My models:
class PersonalUse(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
phone_number = models.IntegerField()
verification = models.IntegerField()
messages = models.BooleanField(default=False)
message_sent = models.BooleanField(default=False)

Django models foreign key not recognizing 'QueryString' BaseObject

I am currently working on a Django 1.5.2 project within a Docker instance that speaks with a mysql database in a separate Docker instance. I am trying to create a Many to Many relationship between two tables by creating a middle table that contains two foreign keys that point to the two tables that need connecting. The problem arises when I run python manage.py syncdb and it spits out the following error to the terminal: NameError: name 'QueryString' is not defined. QueryString is clearly defined in my models.
Here are my Models...
class Tag(models.Model):
name = models.CharField(max_length=100)
class QueryStringTab(models.Model):
tag = models.ForeignKey(Tag, related_name='querystringtab')
querystring = models.ForeignKey(QueryString, related_name='querystringtab')
class QueryString(BaseObject):
"""
Query string holds an SQL statement and query properties for execution
"""
server_id = models.IntegerField()
schema = models.CharField(max_length=255, blank=True)
query = models.CharField(max_length=60000)
variables = models.TextField(blank=True)
created_by = models.ForeignKey(User, related_name='queries_created')
updated_by = models.ForeignKey(User, related_name='queries_last_edited')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField()
touched_by = models.CharField(max_length=1000)
config = models.TextField(blank=True)
runs_started = models.IntegerField(default=0)
runs_completed = models.IntegerField(default=0)
runs_completed_duration = models.IntegerField(default=0) # total number of seconds spent running this query to completion
formats = "pretty_html html json prettyjson csv excel tableau".split()
Noteworthy points...
1) It is recognizing the Tag model just fine.
2) Could it have something to do with the fact that QueryString is a BaseObject
3) It is successfully creating the Tag table in the mysql database
Can anyone find anything obvious that I am doing wrong?
The declaration of QueryStringTab is before the one for QueryStringTab; so when Python evaluates the first, it has not yet seen any definition for the second and therefore reports a NameError.
Django allows you to use a string target than a class object in cases like this:
querystring = models.ForeignKey('QueryString', related_name='querystringtab')
Or, you could simply move the definition of QueryStringTab to the end.

Duplicate model field in Django

A duplicate model field is giving me trouble (no such table appname_modelname when I run my webpage). Whenever I do ./manage.py migrate appname, it gives me "duplicate field". I checked my models.py, there is only one of them there. How do I delete that duplicate field? It seems no matter what I do, it stays. I've tried:
Deleting the database
Deleting migrations folder in app folder
Doing ./manage.py sqlclear south and then dropping the south_migrationhistory table in the dbshell
./manage.py schemamigration appname --initial, ./manage.py migrate appname --fake
I've run out of ideas.
class Document(models.Model):
filename = models.CharField(max_length=255, blank=True, null=True, default=None)
identity = models.CharField(max_length=255, default=None, null=True)
user = models.ForeignKey(User, null=False)
user_id = models.IntegerField(User, null=True)
docfile = models.FileField(upload_to=_upload_path, storage=fs) # upload_to is a path inside the storage path
def get_upload_path(self,filename):
return str(self.user.id) + '/' + str(date.today()) + '/' + filename
You can't do this, for your user foreign key, Django ORM will create a database field named user_id (your foreign key field name plus _id) to use it as a FK in the database.
You don't have to create this field yourself (the ORM will take care), even if you need it, change the name of the attribute user or user_id.
From the documentation:
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column. (You can change this explicitly by specifying db_column) However, your code should never have to deal with the database column name, unless you write custom SQL. You’ll always deal with the field names of your model object.
Not sure but problem causing here in these two line
user = models.ForeignKey(User, null=False)
user_id = models.IntegerField(User, null=True)
Better to use "related name" attribute to avoid the duplicate error as in database "user" will be added as user_id.
user = models.ForeignKey(User, related_name="id_user") # Change the related field as your convenience
user_id = models.IntegerField(null=True, related_name="user_id")
Check if this resolve your issues

Dumpdata with a many-to-many field in Django

I'm running a command to dump my database contents into json format:
python manage.py dumpdata <appname>.<modelname> > file.json
However, it is not dumping my many-to-many field which is called category_id. Well in fact, it is dumping it but the field is consistently empty. Why??
I have tried calling that table directly (which is a category mapping) as such:
python manage.py dumpdata <appname>.<modelname_category_id> > file.json
and I get the following error:
Error: Unable to serialize database: Category matching query does not exist.
I'm using Django 1.2.1 and SQLite backend.
Any hints?
UPDATE: I have tried deleting all rows in the modelname.category_id table, and even with only one row I still get this error.
The table is defined as follows
id: integer PRIMARY KEY
unipart_id: integer
category_id: integer
and both unipart_id and category_id fields are valid and exist.
I have two tables like below,
from django.db import models
class AggregationCategories(models.Model):
name = models.CharField(max_length=50)
class Meta:
db_table = "AggregationCategories"
class AggregationFunctions(models.Model):
name = models.CharField(max_length=50)
aggregation_category = models.ManyToManyField(
AggregationCategories,
related_name='aggregationfunctions_aggregationcategories'
)
class Meta:
db_table = "AggregationFunctions"
When you create many-to-many relationships, you'll get additional table the structure of <model name>_<filed name>. So according to my example model name is AggregationFunctions and the field name is aggregation_category. Based on that my additional table should be AggregationFunctions_aggregation_category. Yes, you can see all three tables in below picture.
So you can dump the data in third table like this, python manage.py dumpdata <app name>.<third table name>. So my app name is catalogue and the third table name is AggregationFunctions_aggregation_category. Based on that my command should be,
python manage.py dumpdata catalogue.AggregationFunctions_aggregation_category
If you've created many-to-many table using ManyToManyField.through, ManyToManyField.through_fields, for an example (directly took it from Django Official Documentation),
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
class Membership(models.Model):
group = models.ForeignKey(Group, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
inviter = models.ForeignKey(
Person,
on_delete=models.CASCADE,
related_name="membership_invites",
)
invite_reason = models.CharField(max_length=64)
Now you have a class call Membership for your many-to-many relationship, so you can use it same as before like this,
python manage.py dumpdata catalogue.Membership
My solution:
appname.modelname_id_category
Dump the data from the third table in a m2m relationship. Its name is myapp_model1_model2.
python manage.py dumpdata myapp.model1_model2 --indent 4 > fixtures/filename.json
Ran into this topic as I was searching how to dump m2m site values from a table and nailed it. I'm on Django 4.
class MyModel(models.Model)
title = models.CharField()
sites = models.ManyToManyField(Site)
...
David's suggestion helped me find:
manage.py dumpdata --format json appname.MyModel_sites

Categories