psycopg2.errors.UndefinedColumn: column excluded.number does not exist - postgresql

I have two tables in two different schemas on one database:
CREATE TABLE IF NOT EXISTS target_redshift.dim_collect_projects (
project_id BIGINT NOT NULL UNIQUE,
project_number BIGINT,
project_name VARCHAR(300) NOT NULL,
connect_project_id BIGINT NOT NULL,
project_desc VARCHAR(5000) NOT NULL,
project_type VARCHAR(50) NOT NULL,
project_status VARCHAR(100),
project_path VARCHAR(32768),
language_code VARCHAR(10),
country_code VARCHAR(10),
timezone VARCHAR(10),
project_created_at TIMESTAMP WITHOUT TIME ZONE,
project_modified_at TIMESTAMP WITHOUT TIME ZONE,
date_created TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(),
date_updated TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS source_redshift.dim_collect_projects (
id BIGINT NOT NULL UNIQUE,
number BIGINT,
name VARCHAR(300) NOT NULL,
connect_project_id BIGINT NOT NULL,
description VARCHAR(5000) NOT NULL,
type VARCHAR(50) NOT NULL,
status VARCHAR(100),
path VARCHAR(32768),
language VARCHAR(10),
country VARCHAR(10),
timezone VARCHAR(10),
created TIMESTAMP WITHOUT TIME ZONE NULL DEFAULT NOW(),
modified TIMESTAMP WITHOUT TIME ZONE NULL DEFAULT NOW()
);
I need to copy data from the second table to the first.
Do it so:
INSERT INTO target_redshift.dim_collect_projects AS t
SELECT id, number, name, connect_project_id, description,
type, status, path, language, country, timezone, created,
modified
FROM source_redshift.dim_collect_projects
ON CONFLICT (project_id)
DO UPDATE SET
(t.project_number, t.project_name, t.connect_project_id, t.project_desc,
t.project_type, t.project_status, t.project_path, t.language_code,
t.country_code, t.timezone, t.project_created_at, t.project_modified_at,
t.date_created, t.date_updated) = (EXCLUDED.number, EXCLUDED.name, EXCLUDED.connect_project_id,
EXCLUDED.description, EXCLUDED.type, EXCLUDED.status,
EXCLUDED.path, EXCLUDED.language, EXCLUDED.country,
EXCLUDED.timezone, EXCLUDED.created, EXCLUDED.modified, t.date_created, NOW())
And AirFlow send an error:
psycopg2.errors.UndefinedColumn: column excluded.number does not exist
LINE 12: t.date_created, t.date_updated) = (EXCLUDED.number, ...

You need to use the target_redshift.dim_collect_projects field names for the excluded.* fields e.g. excluded.project_number. The target table is the controlling one for the column names as that is where the data insert is being attempted.
UPDATE
Using an example table from my test database:
\d animals
Table "public.animals"
Column | Type | Collation | Nullable | Default
--------+------------------------+-----------+----------+---------
id | integer | | not null |
cond | character varying(200) | | not null |
animal | character varying(200) | | not null |
Indexes:
"animals_pkey" PRIMARY KEY, btree (id)
\d animals_target
Table "public.animals_target"
Column | Type | Collation | Nullable | Default
---------------+------------------------+-----------+----------+---------
target_id | integer | | not null |
target_cond | character varying(200) | | |
target_animal | character varying(200) | | |
Indexes:
"animals_target_pkey" PRIMARY KEY, btree (target_id)
insert into
animals_target
select
*
from
animals
ON CONFLICT
(target_id)
DO UPDATE SET
(target_id, target_cond, target_animal) =
(excluded.target_id, excluded.target_cond, excluded.target_animal);
NOTE: No use of table alias for the table being inserted into.
The target table is the one the data is being inserted into. The attempted INSERT is into its columns so the they are the ones that are being potentially excluded.

For anyone who might come here later, I had a table which was created from an Excel import, and unwittingly one of the column names started with a Unicode character (in other words, an invisible character).
ERROR: column excluded.columnname does not exist
LINE 5: ... (yada, yada) = (excluded.columnname, excluded.yada)
HINT: Perhaps you wanted to reference the column "excluded.columnname".
Since none of the answers have been marked as correct, I suggest that errors like the above may arise even though everything looks to be perfectly fine if a column name begins with one of these invisible characters. At least, that was the case for me and I had to scratch my head for quite a while before I figured it out.
One way to avoid such issues could be to not create tables automatically based on the contents of Excel files.

Did it:
INSERT INTO dim_collect_projects_1 AS t (project_id, project_number, project_name, connect_project_id, project_desc,
project_type, project_status, project_path, language_code,
country_code, timezone, project_created_at, project_modified_at)
SELECT s.id, s.number, s.name, s.connect_project_id, s.description,
s.type, s.status, s.path, s.language, s.country, s.timezone, s.created,
s.modified
FROM dim_collect_projects_2 AS s
ON CONFLICT (project_id)
DO UPDATE SET
(project_number, project_name, connect_project_id, project_desc,
project_type, project_status, project_path, language_code,
country_code, timezone, project_created_at, project_modified_at,
date_updated) = (EXCLUDED.project_number,
EXCLUDED.project_name, EXCLUDED.connect_project_id,
EXCLUDED.project_desc, EXCLUDED.project_type, EXCLUDED.project_status,
EXCLUDED.project_path, EXCLUDED.language_code, EXCLUDED.country_code,
EXCLUDED.timezone, EXCLUDED.project_created_at,
EXCLUDED.project_modified_at, NOW())
WHERE t.project_number != EXCLUDED.project_number
OR t.project_name != EXCLUDED.project_name
OR t.connect_project_id != EXCLUDED.connect_project_id
OR t.project_desc != EXCLUDED.project_desc
OR t.project_type != EXCLUDED.project_type
OR t.project_status != EXCLUDED.project_status
OR t.project_path != EXCLUDED.project_path
OR t.language_code != EXCLUDED.language_code
OR t.country_code != EXCLUDED.country_code
OR t.timezone != EXCLUDED.timezone
OR t.project_created_at != EXCLUDED.project_created_at
OR t.project_modified_at != EXCLUDED.project_modified_at;

Related

Duplicate key found, but nothing matches in the table

I have a function which receives some parameters, does a SELECT to see if a table row exists and returns FALSE if so. If not, it does an INSERT but currently always fails with a 'duplicate key'. Here's a pseudo-code version...
CREATE OR REPLACE FUNCTION bob_function (
p_work_id INTEGER,
p_location_id VARCHAR,
p_area_id VARCHAR,
p_scheduled_work_no INTEGER,
p_start_date_time TIMESTAMPTZ,
p_work_date_time TIMESTAMPTZ,
p_user_id INTEGER,
p_comments TEXT,
p_work_stat_code CHAR(1)
)
RETURNS BOOLEAN AS $$
BEGIN
IF EXISTS (
SELECT 1
FROM work_table
WHERE location_id = p_location_id
AND area_id = p_area_id
AND work_id = p_work_id
AND scheduled_work_no = p_scheduled_work_no
AND start_date_time = p_start_date_time
AND user_work_id = p_user_id
AND work_date_time = p_work_date_time
)
THEN
RAISE NOTICE 'Work already exists - SKIPPING';
RETURN FALSE;
END IF;
INSERT INTO work_table (
location_id,
area_id,
work_id,
scheduled_work_no,
start_date_time,
user_work_id,
work_date_time,
stat_code,
comment
)
VALUES (
p_location_id,
p_area_id,
p_work_id,
p_scheduled_work_no,
p_start_date_time,
p_user_id,
p_work_date_time,
v_work_stat_code,
p_comments
);
RETURN TRUE;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
The primary key is defined thus...
myDb=# \d task_work_pk
Index "schema1.task_work_pk"
Column | Type | Key? | Definition
-------------------+-----------------------------+------+-------------------
location_id | character varying(8) | yes | location_id
area_id | character varying(3) | yes | area_id
work_id | integer | yes | work_id
scheduled_work_no | integer | yes | scheduled_work_no
start_date_time | timestamp(0) with time zone | yes | start_date_time
user_work_id | integer | yes | user_work_id
work_date_time | timestamp(0) with time zone | yes | work_date_time
primary key, btree, for table "schema1.work_table"
Currently I get the following error every time I run this function...
ERROR: 23505: duplicate key value violates unique constraint "task_work_pk"
DETAIL: Key (location_id, area_id, work_id, scheduled_work_no, start_date_time, user_work_id, work_date_time)=(SITE_1, BOB, 218, 5, 2021-07-09 00:28:00+10, 1, 2021-07-09 21:00:15+10) already exists.
There are no rows whatsoever with work_id = 218 and this is the only place in the entire database where this table is written to. The function is only called no more frequently than once a minute and I'm 99% sure I've not got any race condition.
EDIT: updated to remove errors
I'm ignoring your PLPGSQL code because it is not real code and has obvious flaws.
Given that 218 doesn't exist the only way to cause that error without 218 pre-existing is to insert the same record twice in a single transaction.

List Partitioning in Postgres 12

CREATE TABLE countrymeasurements
(
countrycode int NOT NULL,
countryname character varying(30) NOT NULL,
languagename character varying (30) NOT NULL,
daysofoperation character varying(30) NOT NULL,
salesparts bigint,
replaceparts bigint
)
PARTITION BY LIST(countrycode)
(
partition india values(1),
partition japan values(2),
partition china values(3),
partition malaysia values(4)
);
I am getting ERROR: syntax error at or near "(". What i am missing here. I am using postgres12
I don't know where you found that syntax, obviously not in the manual. As you can see there partitions are created using create table .. as partition of in Postgres:
Define the table:
CREATE TABLE countrymeasurements
(
countrycode int NOT NULL,
countryname character varying(30) NOT NULL,
languagename character varying (30) NOT NULL,
daysofoperation character varying(30) NOT NULL,
salesparts bigint,
replaceparts bigint
)
PARTITION BY LIST(countrycode);
Define the partitions:
create table india
partition of countrymeasurements
for values in (1);
create table japan
partition of countrymeasurements
for values in (2);
create table china
partition of countrymeasurements
for values in (3);
create table malaysia
partition of countrymeasurements
for values in (4);
Welcome to stackoverflow! Please note, that asking questions here without showing prior research may turn away people that otherwise might love to help.
In this case I checked and found no official example for list partitioning. But, if you just shorten your statement it will create a table using the values in countrycode column to partition:
CREATE TABLE countrymeasurements
(
countrycode int NOT NULL,
countryname character varying(30) NOT NULL,
languagename character varying (30) NOT NULL,
daysofoperation character varying(30) NOT NULL,
salesparts bigint,
replaceparts bigint
)
PARTITION BY LIST(countrycode)
;
The psql describe table command shows the partitioning is as requested:
psql=# \d countrymeasurements
Table "public.countrymeasurements"
Column | Type | Collation | Nullable | Default
-----------------+-----------------------+-----------+----------+---------
countrycode | integer | | not null |
countryname | character varying(30) | | not null |
languagename | character varying(30) | | not null |
daysofoperation | character varying(30) | | not null |
salesparts | bigint | | |
replaceparts | bigint | | |
Partition key: LIST (countrycode)
Then you can define the partitions like in the answer from #a_horse_with_no_name. But, some notes on using such a strategy may be in order.
Notes:
When you just allow 4 explicit partitions via list (as you tried) what happens when value 5 comes along?
The documentation at postgresql 12 on ddl partition ing suggests to consider hash partitioning instead of list and choose the number of partitions instead of relying on your column values which might expose a very unbalanced abundance.

How to get the standard price field value in odoo?

I have problem.
The standard_price is computed field and not stored product_template, product_product table. How to get the standard price field value in odoo xlsx report?
The error is:
Record does not exist or has been deleted.: None
Help, I need any solution and idea?
Check the cost field of the product_price_history table. I think that is what you are looking for. This table is related with the product_product table through the field product_id:
base=# \dS product_price_history
Table "public.product_price_history"
Column | Type | Modifiers
-------------+-----------------------------+--------------------------------------------------------------------
id | integer | not null default nextval('product_price_history_id_seq'::regclass)
create_uid | integer |
product_id | integer | not null
company_id | integer | not null
datetime | timestamp without time zone |
cost | numeric |
write_date | timestamp without time zone |
create_date | timestamp without time zone |
write_uid | integer |
Indexes:
"product_price_history_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"product_price_history_company_id_fkey" FOREIGN KEY (company_id) REFERENCES res_company(id) ON DELETE SET NULL
"product_price_history_create_uid_fkey" FOREIGN KEY (create_uid) REFERENCES res_users(id) ON DELETE SET NULL
"product_price_history_product_id_fkey" FOREIGN KEY (product_id) REFERENCES product_product(id) ON DELETE CASCADE
"product_price_history_write_uid_fkey" FOREIGN KEY (write_uid) REFERENCES res_users(id) ON DELETE SET NULL

Peewee Python Default is not reflecting in DateTimeField

Not able to set default timestamp in spite of using DateTimeField(default=datetime.datetime.now)
The column is set to not null but no default value is set
I have my model
import datetime
database = PostgresqlDatabase(dbname,username,password,host)
class BaseModel(Model):
class Meta:
database = database
class UserInfo(BaseModel):
id = PrimaryKeyField()
username = CharField(unique=True)
password = CharField()
email = CharField(null=True)
created_date = DateTimeField(default=datetime.datetime.now)
when I create table using this model and below code
database.connect()
database.create_tables([UserInfo])
I am getting below table
Table "public.userinfo"
Column | Type | Modifiers
--------------+-----------------------------+------------------------- ------------------------------
id | integer | not null default nextval('userinfo_id_seq'::regclass)
username | character varying(255) | not null
password | character varying(255) | not null
email | character varying(255) |
created_date | timestamp without time zone | not null
Indexes:
"userinfo_pkey" PRIMARY KEY, btree (id)
"userinfo_username" UNIQUE, btree (username)
Here in table created date doesn't set to any default
When using the default parameter, the values are set by Peewee rather than being a part of the actual table and column definition
try created_date = DateTimeField(constraints=[SQL('DEFAULT CURRENT_TIMESTAMP')])

postgresql 8.4 trigger/storedproc error : how to fix it?

An INSERT on a table triggers a stored proc where the following error occurs.
ERROR: column "targetedfamily" is of type boolean but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Where: PL/pgSQL function "fn_family_audit" line 19 at SQL statement
And here's the ERRING stored proc (notice that my attempt to fix the problem by doing CAST(NEW.targetedfamily AS BOOLEAN) does NOT seem to work)
CREATE OR REPLACE FUNCTION fn_family_audit() RETURNS TRIGGER AS $tr_family_audit$
BEGIN
--
-- Create a row in family_audit to reflect the operation performed on family,
-- make use of the special variable TG_OP to work out the operation.
--
IF (TG_OP = 'DELETE') THEN
INSERT INTO public.family_audit values (
DEFAULT, 'D', OLD.family_id, OLD.familyserialno, OLD.node_id, OLD.sourcetype, OLD.familyname,
OLD.familynamelocallang, OLD.hofname, OLD.hofnamelocallang, OLD.targetedfamily, OLD.homeless,
OLD.landless, OLD.dependentonlabour, OLD.womenprimaryearner, OLD.landlinenumber, OLD.username , now());
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO public.family_audit values(
DEFAULT, 'U',NEW.family_id, NEW.familyserialno, NEW.node_id, NEW.sourcetype, NEW.familyname,
NEW.familynamelocallang, NEW.hofname, NEW.hofnamelocallang, NEW.targetedfamily, NEW.homeless,
NEW.landless, NEW.dependentonlabour, NEW.womenprimaryearner, NEW.landlinenumber, NEW.username , now());
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO public.family_audit values(
DEFAULT, 'I',NEW.family_id, NEW.familyserialno, NEW.node_id, NEW.sourcetype, NEW.familyname,
NEW.familynamelocallang, NEW.hofname, NEW.hofnamelocallang, CAST(NEW.targetedfamily AS BOOLEAN), NEW.homeless,
NEW.landless, NEW.dependentonlabour, NEW.womenprimaryearner, NEW.landlinenumber, NEW.username , now());
RETURN NEW;
END IF;
RETURN NULL; -- result is ignored since this is an AFTER trigger
END;
$tr_family_audit$ LANGUAGE plpgsql;
Here's the table definition
nucleus4=# \d family;
Table "public.family"
Column | Type | Modifiers
---------------------+-----------------------------+------------------------------------------------------------
family_id | integer | not null default nextval('family_family_id_seq'::regclass)
familyserialno | integer | not null
sourcetype | character varying(20) | not null
familyname | character varying(100) |
familynamelocallang | character varying(255) |
hofname | character varying(100) | not null
hofnamelocallang | character varying(255) | not null
targetedfamily | boolean |
homeless | boolean |
landless | boolean |
dependentonlabour | boolean |
womenprimaryearner | boolean |
landlinenumber | character varying(20) |
username | character varying(20) | not null
adddate | timestamp without time zone | not null default now()
updatedate | timestamp without time zone | not null default now()
node_id | integer | not null
Indexes:
"PK_family" PRIMARY KEY, btree (family_id)
"family_idx" UNIQUE, btree (familyserialno, node_id)
Foreign-key constraints:
"family_fk" FOREIGN KEY (node_id) REFERENCES hierarchynode_master(node_id)
Referenced by:
TABLE "agriland" CONSTRAINT "FK_agriland_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "currentloans" CONSTRAINT "FK_currentloans_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "family_address" CONSTRAINT "FK_family_address_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "family_basic_info" CONSTRAINT "FK_family_basic_info_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "family_entitlement" CONSTRAINT "FK_family_entitlement_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "livestock" CONSTRAINT "FK_livestock_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "member" CONSTRAINT "FK_member_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
TABLE "otherassets" CONSTRAINT "FK_otherassets_family" FOREIGN KEY (family_id) REFERENCES family(family_id) ON UPDATE RESTRICT ON DELETE RESTRICT
Triggers:
tr_family_audit AFTER INSERT OR DELETE OR UPDATE ON family FOR EACH ROW EXECUTE PROCEDURE fn_family_audit()
tr_family_updatedate BEFORE UPDATE ON family FOR EACH ROW EXECUTE PROCEDURE fn_modify_updatedate_column()
nucleus4=#
Here's family_audit
nucleus4=# \d family_audit;
Table "public.family_audit"
Column | Type | Mod
---------------------+-----------------------------+----------------------------------
familyaudit_id | integer | not null default nextval('family_
operation | character(1) | not null
family_id | integer | not null
familyserialno | integer | not null
sourcetype | character varying(20) | not null
familyname | character varying(100) |
familynamelocallang | character varying(255) |
hofname | character varying(100) | not null
hofnamelocallang | character varying(255) | not null
targetedfamily | boolean |
homeless | boolean |
landless | boolean |
dependentonlabour | boolean |
womenprimaryearner | boolean |
landlinenumber | character varying(20) |
username | character varying(20) | not null
adddate | timestamp without time zone | not null default now()
node_id | integer | not null
Indexes:
"PK_family_audit" PRIMARY KEY, btree (familyaudit_id)
nucleus4=#
Here's the trigger
CREATE TRIGGER tr_family_audit
AFTER INSERT OR UPDATE OR DELETE ON public.family
FOR EACH ROW EXECUTE PROCEDURE fn_family_audit();
I would appreciate any hints.
Thank you,
BR,
~A
Your problem is here:
NEW.hofnamelocallang
Your insert has one extra column (apparently NEW.node_id). Try changing your insert to:
INSERT INTO public.family_audit values(
DEFAULT, 'I',NEW.family_id, NEW.familyserialno,
NEW.sourcetype, NEW.familyname,
NEW.familynamelocallang, NEW.hofname, NEW.hofnamelocallang,
NEW.targetedfamily, NEW.homeless,
NEW.landless, NEW.dependentonlabour, NEW.womenprimaryearner,
NEW.landlinenumber, NEW.username , now()
);
The error you are getting is basically saying that you were trying to insert NEW.hofnamelocallang into targetedfamily column (which is boolean, not varchar) because of the extra column you were putting in the insert sentence.
I would advice that, when you are performing an insert, for sanity reasons, always enumerate the columns you are putting values into. Something like this:
insert into table foo
(col1, col2, col3) -- column enumeration here
values
(1, 2, 3);