I have a Django project that started as an import of a legacy database. Because of this, there is a model with a composite primary key. This worked as long as I used only the legacy data, but now I want to add new data and the form I created is telling me that I am trying to insert duplicate data, presumably because it is only looking at one of the fields as the primary key.
Now I want to change the model to use an autoincrement primary key, like one Django would automatically add. I tried removing the primary key attributes from the fields and putting them in unique_together in the Meta inner class. When I ran schemamigration with South, it wanted to add an id field as expected, but it asked for a default value.
How can I specify that South should assign unique keys in some way that is reasonable for an autoincrement field? (i.e. assign the sequence [1...n] to some arbitrary ordering of the records)
If this is impossible is there another way to accomplish the same thing, preferably using Django and South?
I solved the problem that required me to do this with a workaround:
I copied the data from the original table into a temporary table in SQL with INSERT INTO... SELECT.... I then deleted the original table and recreated it with the autoincrement field. Then I copied the data back into the new table, with the autoincrement values added automatically by the INSERT command. Finally I executed a fake run of the South migration to make South's tables consistent with the new schema.
Related
I migrated my Django database from Sqlite into Postgres, the data is properly set and tested when reading.
The thing is that, when I try to add a new registry into the table, Django is using id number as 1 instead to be the last registry id plus one.
That of course returns an error, something like this:
IntegrityError at /admin/accounting/expense/add/
duplicate key value violates unique constraint "accounting_expense_pkey"
DETAIL: Key (id)=(2) already exists.
How can I make Django to use the proper id number when trying to save a registry?
I'm aware there is a way to set Django to begin the count on a specific number, but I wanted to know if there is a way to tell Django to look at the database (which is populated) and use that id count.
I am using Django to develop new software to replace a legacy one, and all my new models have auto-increment primary keys. I want to import records from the legacy database keeping their original primary keys (users know them all), but I don't know how to do it with auto-increment primary keys.
Is it possible to create my models with integer primary keys and change them to auto-increment ones without losing their data?
It is possible to have an IntegerField as primary key without auto-increment feature. You can do this by
id = models.PositiveIntegerField(primary=True)
And once you import all your data, you can convert it to AutoIncrement by replacing PositiveIntegerField to AutoField.
Solution-2
You can specify id of your row during data import while having default AutoField and it will load data properly. So no need worry here.
I have deleted one column from my model. Then I deleted database, migration files, venv direcotry, and pycache. But after executing makemigrations the old db schema is generating ( it still contains this column). What is the problem. How django knows about this column. It's no longer present in data model.
Django automatically creates a primary key column if you don't define one in your model. It is explained here:
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
If you’d like to specify a custom primary key, specify primary_key=True on one of your fields. If Django sees you’ve explicitly set Field.primary_key, it won’t add the automatic id column.
Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
Since you happened to declare it explicitly with the same defaults, you won't notice any difference.
you also need to run python manage.py migrate after makemigrations to commit the changes to the database, then everything should be fine
I have seen several questions and answers on SO, most were three years old or older and I looked at the Django documentation (hoping I didn't miss it). I have to have a 9+ digit number for an id. Most responses were to do this at the database. I am guessing that means to create the model in Django and then go back to the database and change the id column Django created with a new starting/next value attribute on the column.
If not how can I create a database table from Django, Code First, that allows me to create a table with an id column that starts at 100000000? And, it be done with the stock model object methods in Django. I don't really want to do a special hack. If that is the case, I can go the database and fix the column. I was trying to adhere to the Code First ideas of Django (though I prefer database first, and am afraid using inspectdb will make a mess.)
Edit: I didn't want to use UUID. I believe BigAutoField is best.
You should be able to do this in two steps:
1 - Specify your primary key explicitly using primary_key=TRUE in your model definition. See the Django docs for more info. You can then specify BigAutoField or whatever other type you want for the primary key.
2A - If you're populating the database up front, just set pk: 100000000 in your fixture.
OR
2B - If you're not populating the database up front, use Django Model Migration Operations RunSQL as detailed here. For your SQL use ALTER TABLE tableName AUTO_INCREMENT=100000000.
In addition to my primary key, I would like to set up one or more alternate keys in my model in Django. For example, perhaps the primary key in the customer table is a Django-generated ID. But, I may want another, alternate key to ensure that no customer-name, insert-date combination is duplicated. Is there a way to do this in Django or must I go out and do this in the database?
Thanks!