Hi Michel,
So, a little explanation of why you're facing this issue:
When you create an "auto-increment" field in Postgres, Postgres creates something called a "sequence" to keep track of the increments. If you were to `psql` into your database and check the schema of the table, you'll see the `id` field defined with something like:
id | integer | | not null | nextval('content_id_seq'::regclass)
What this means is that to assign the `id` to an object, it will call the "nextval" function on the "content_id_seq" sequence, to get the next number in the sequence. In the normal flow of things, this is not a problem. Every time you insert a new record into the table, it increments the sequence by calling the "nextval" operation and populates the id, and the same for the subsequent row insertion and so on.
Now, the problem arises if you imported data "directly" into the database, i.e. INSERTed rows including the id, in which case, the database will never call the "nextval" function internally, and the "sequence" it uses to keep track of the incrementing ids will never have been updated. I.e. if you manually insert 3000 rows with ids, the nextval() operation on the sequence is never called, and hence postgres still thinks the "sequence" is at 1, and therefore tries to assign the id of, say "2" to the next item, and then of course fails since there is already an item that you manually inserted with id 2.
There would be two ways to solve this:
- 1> When importing the data, leave out the `id` field, and let postgres populate the id field automatically using the auto-increment nextval() function so the sequence stays in sync.
- 2> The other option is to manually reset the sequence to be at whatever your highest id value is.
The way to manually update the sequence:
For each table where you are facing this problem:
Run `\d` to see the table schema and get the name of the "sequence" ^^ in my example above, the sequence name is "content_id_seq" - it will generally follow the format of <model_name>_id_seq .
Fetch the highest current id with:
SELECT id FROM <table_name> ORDER BY id DESC LIMIT 1;
Reset the sequence to the value of the highest id:
SELECT setval('content_id_seq', 4555, true); # assuming your sequence is called content_id_seq and the highest id was 4555 .
If doing this individually for each table in the db seems a bit tedious, you will find various scripts and solutions to automate the process a bit more by searching for something like "postgres reset sequence" - this is a fairly common problem and you should find a bunch of material online.