I’m trying to update a lot of row in my database using unnest()
.
Here’s my db:
JavaScript
x
10
10
1
create table my_table
2
(
3
id serial,
4
feat bytea,
5
primary key (id)
6
);
7
8
create index ix_my_table_id
9
on my_table (id);
10
Then I update the table with:
JavaScript
1
13
13
1
import numpy as np
2
3
data = [(np.random.random(20).tobytes(), i) for i in range(100)]
4
cursor.execute(
5
"""
6
UPDATE my_table
7
SET feat = s.feat
8
FROM unnest(%s) s(feat bytea, id integer)
9
WHERE id = s.id;
10
""", (data,),
11
)
12
13
But I got the following error:
JavaScript
1
32
32
1
File ".../python3.8/site-packages/psycopg/cursor.py", line 551, in execute
2
self._conn.wait(
3
File ".../python3.8/site-packages/psycopg/connection.py", line 776, in wait
4
return waiting.wait(gen, self.pgconn.socket, timeout=timeout)
5
File ".../python3.8/site-packages/psycopg/waiting.py", line 219, in wait_epoll
6
s = next(gen)
7
File ".../python3.8/site-packages/psycopg/cursor.py", line 196, in _execute_gen
8
pgq = self._convert_query(query, params)
9
File ".../python3.8/site-packages/psycopg/cursor.py", line 379, in _convert_query
10
pgq.convert(query, params)
11
File ".../python3.8/site-packages/psycopg/_queries.py", line 84, in convert
12
self.dump(vars)
13
File ".../python3.8/site-packages/psycopg/_queries.py", line 95, in dump
14
self.params = self._tx.dump_sequence(params, self._want_formats)
15
File ".../python3.8/site-packages/psycopg/_transform.py", line 152, in dump_sequence
16
out[i] = dumper.dump(param)
17
File ".../python3.8/site-packages/psycopg/types/array.py", line 167, in dump
18
dump_list(obj)
19
File ".../python3.8/site-packages/psycopg/types/array.py", line 154, in dump_list
20
ad = self._dump_item(item)
21
File ".../python3.8/site-packages/psycopg/types/array.py", line 173, in _dump_item
22
return self.sub_dumper.dump(item)
23
File ".../python3.8/site-packages/psycopg/types/composite.py", line 66, in dump
24
return self._dump_sequence(obj, b"(", b")", b",")
25
File ".../python3.8/site-packages/psycopg/types/composite.py", line 47, in _dump_sequence
26
ad = b'"' + self._re_esc.sub(rb"11", ad) + b'"'
27
File ".../3.8.10/lib/python3.8/re.py", line 332, in filter
28
return sre_parse.expand_template(template, match)
29
File ".../3.8.10/lib/python3.8/sre_parse.py", line 1064, in expand_template
30
return empty.join(literals)
31
AttributeError: 'memoryview' object has no attribute 'join'
32
However, it’s working if I do a classic update. Any idea ?
JavaScript
1
3
1
Python: 3.8.10
2
psycopg: 3.0.13
3
Advertisement
Answer
Since your data is a 2×100 matrix, is better to partition it in vectors (1d array) for each parameter as follows:
JavaScript
1
8
1
cursor.execute(
2
"""
3
UPDATE my_table mt
4
SET feat = s.feat
5
FROM (select unnest(%s) id, unnest(%s) feat) s
6
WHERE mt.id = s.id;
7
""", ([row[1] for row in data],[row[0] for row in data]),)
8