django-test-migrations failing when using multiple postgres schemas in django - django

I am using local postgres 12 db.
I have 2 models:
class CustomUser2(models.Model):
name = models.CharField(max_length=100)
class CustomUser3(models.Model):
name = models.CharField(max_length=100)
class Meta:
db_table = 'schema1\".\"custom_user_3'
I run following test:
from django_test_migrations.contrib.unittest_case import MigratorTestCase
class TestDirectMigration(MigratorTestCase):
"""This class is used to test direct migrations."""
migrate_from = ('core', '0002_customuser2')
migrate_to = ('core', '0003_customuser3')
def prepare(self):
"""Prepare some data before the migration."""
SomeItem = self.old_state.apps.get_model('core', 'CustomUser2')
def test_migration_main0003(self):
"""Run the test itself."""
SomeItem = self.new_state.apps.get_model('core', 'CustomUser2')
I get following error:
django.db.utils.ProgrammingError: relation "custom_user_3" already exists
Is there a way to test migrations when using different schemas in django + postgres ?

Related

Django + Graphene + DjangoModelFormMutation : dissociating create and update

I am using a DjangoModelFormMutation from Graphene-python to expose a generic mutation for a model, like so :
from graphene import Field
from graphene_django.forms.mutation import DjangoModelFormMutation
from django.db import models
class Pet(models.Model):
name = models.CharField()
legs = models.PositiveIntegerField()
class PetForm(forms.ModelForm):
class Meta:
model = Pet
fields = ('name', 'legs')
# This will get returned when the mutation completes successfully
class PetType(DjangoObjectType):
class Meta:
model = Pet
class PetMutation(DjangoModelFormMutation):
pet = Field(PetType)
class Meta:
form_class = PetForm
Then in my schema file, I register the mutation like this :
create_pet = mutations.PetMutation.Field()
update_pet = mutations.PetMutation.Field()
This works, but there are two desired behaviors I can't achieve this way :
Have two different mutations : one for create that can only create and not update, and one for update that can only update, and not create.
Have the update mutation work partially as well , i.e only updating the client-provided fields.
How can I achieve the desired behavior ?

Making use of the users table, causing an error

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

Django error: multiple default values for specified column "id"

I'm working with a project with docker-compose, where I have a postgre container.
When I run:
docker-compose -f dev.yml run django python manage.py migrate
I get the error:
django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "scrapy_scrapy"
That is happening before I made some changes to my models.py file. But now the file is correct and should be working. This is the content of the models.py file:
from django.db import models
import django
# Create your models here.
class Scrapy(models.Model):
user = models.CharField(max_length=50,blank=True)
password = models.CharField(max_length=50,blank=True)
projecte = models.CharField(max_length=100)
estat_last_check = models.CharField(max_length=700, default="", blank=True)
date = models.DateTimeField(default=django.utils.timezone.now, blank=True)
app_label = ''
def __str__(self): # __unicode__ on Python 2
return self.projecte + " - " + self.user
class Meta:
app_label = 'scrapy'
As you can see, no id filed is defined anymore, so, why is complaining about that field?
I've done my research and tried some possible solutions, but no luck. I've already tried deleting the full Docker container and creating it again, or trying to delete the database.
Any ideas?

unique_together does not work in Django shell

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.

How to represent a many-to-many mapping as array-field in materialized view in PostgreSQL?

I am trying to create materialized view in postgresql using django by following this blog post.
my models are:
class Occasion(models.Model):
name = models.CharField(max_length=100)
class ItemType(models.Model):
name = models.CharField(max_length=100)
class Dress(models.Model):
name = models.CharField(max_length=100)
item_type = models.ForeignKey(ItemType)
occasions = models.ManyToManyField(Occasion)
# ... more fields
Now, I create a model corresponding to the materialized view (purpose of creating this view is to minimize join queries):
class DressMaterializedView(models.Model):
name = models.CharField(max_length=100)
item_type_name = models.CharField(max_length=100) # note this
occasion_names = models.ArrayField( # and this
models.CharField(max_length=100) # and compare it with Dress model above
)
class Meta:
managed = False
db_table = "dresses_dressmv"
Now, What SQL query (ie. CREATE MATERIALIZED VIEW dresses_dressmv ...) do I write to create the materialized view I intend to.
Thanks in advance.
Why dont you use Arrayfield provided by django OR for Django-Postgres you can have Jsonfield option but for that you need to use django 1.9 and postgres 9.4 mandatory
for reference you can have look at This