Issue: Postgres on_conflict quirks
Author: rammie
State: closed
Created: 2018-02-22 17:41:16

First off, many thanks for supporting upsert functionality in peewee 3.0! I'm using postgres as the db engine and ran into a quirk:

```python
class Model(Model):
    a = CharField(index=True)
    c = IntegerField(default=0)

cls = Model

# Does not work
# Produces error:
# ProgrammingError: column reference "c" is ambiguous
cls.insert({
    cls.a: "Hello world",
    cls.c: 5
}).on_conflict(
    conflict_target=(cls.a, ),
    update={cls.c: cls.c + 5}
).execute()


# works!
cls.insert({
    cls.a: "Hello world",
    cls.c: 5
}).on_conflict(
    conflict_target=(cls.a, ),
    update={cls.c: SQL("%s.c" % cls._meta.table_name) + 5}
).execute()
```

The same issue affects the where clause of the on_conflict statements in postgres as well. For example,

```python
# Does not work
cls.insert({
    cls.a: "Hello world",
    cls.c: 5
}).on_conflict(
    conflict_target=(cls.a, ),
    update={cls.c: 5},
    where=(cls.c < 5)
).execute()

# works!
cls.insert({
    cls.a: "Hello world",
    cls.c: 5
}).on_conflict(
    conflict_target=(cls.a, ),
    update={cls.c: 5},
    where=(SQL("%s.c" % cls._meta.table_name) < 5)
).execute()
```

Thanks for reporting. Fucking stupid-ass postgres with it's janky raggedy-ass overly-complicated upsert and rules for using aliases in insert queries...grumble grumble.

Working on a fix.

Thanks again for the very helpful report -- added tests and have it working: e642ab9e35603a565d89240b62e0e93c532e569e

Wow, thanks for the quick fix as always. Very excited to start using it, can't wait to port my raw upsert queries to peewee 3.0. And yeah, fuck their stupid rules for using aliases in insert queries.

Cool, keep me posted if you run into issues. Pushed 3.0.20 which contains this latest fix.

Hello, I have the same issue with insert_from method.
Do you know how to fix this?

```
Traceback (most recent call last):
  File "...\venv\lib\site-packages\peewee.py", line 2484, in execute_sql
    cursor.execute(sql, params or ())
psycopg2.ProgrammingError: la referencia a la columna «source_cd» es ambigua
LINE 1: ..._name", "source_cd" = EXCLUDED."source_cd" WHERE ("source_cd...
```

Can you provide an example?

I need update rows only when source_cd is different than 1

*Code*
```
    person_alias = Person.alias('x')
    inst = person_alias.insert_from(
        person_raw_ext.select(person_raw_ext.ext_person_cd,
                              person_raw_ext.ext_person_formatted_cd,
                              person_raw_ext.ext_person_name,
                              person_raw_ext.ext_source_cd),
        [person_alias.code, person_alias.formatted,
         person_alias.name, person_alias.source_cd]) \
        .on_conflict(conflict_target=Person.code,
                     preserve=[Person.name, Person.source_cd],
                     where=(person_alias.source_cd != 1))

    print(inst.sql())
    inst.execute()
```

*Output*
```
('INSERT INTO "public"."person" ("person_cd", "person_formatted_cd", "person_name", "source_cd") SELECT "t1"."ext_person_cd", "t1"."ext_person_formatted_cd", "t1"."ext_person_name", "t1"."ext_source_cd" FROM "lnd_sii"."vw_person_ext" AS "t1" ON CONFLICT ("person_cd") DO UPDATE SET "person_name" = EXCLUDED."person_name", "source_cd" = EXCLUDED."source_cd" WHERE ("source_cd" != %s) RETURNING "person_cd"', [1])
Traceback (most recent call last):
  File "C:\Users\ah250065\Documents\Personal\bidding\bidding-etl\venv\lib\site-packages\peewee.py", line 2484, in execute_sql
    cursor.execute(sql, params or ())
psycopg2.ProgrammingError: la referencia a la columna «source_cd» es ambigua
LINE 1: ..._name", "source_cd" = EXCLUDED."source_cd" WHERE ("source_cd...
                                                             ^
```


muchas gracias, I'll put together a failing test and see if I can work out a solution.

You might try a couple things:

* upgrade to the latest peewee if you haven't already
* looks like you're using `person_alias` in some places and `Person` in others -- try just using `Person` throughout as the alias doesn't seem necessary in the example given

Attempted to replicate the query here: 7946037c40030ea5dd7539b054562bf19f57c317 -- the test is passing, though the sql looks a bit different than in your example -- namely, the where clause column reference is fully-qualified.