Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jJkiO-0000w4-4d for psycopg@arkaria.postgresql.org; Wed, 01 Apr 2020 21:16:00 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jJkiN-0001yJ-2E for psycopg@arkaria.postgresql.org; Wed, 01 Apr 2020 21:15:59 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jJkiM-0001xi-SS for psycopg@lists.postgresql.org; Wed, 01 Apr 2020 21:15:58 +0000 Received: from out1-smtp.messagingengine.com ([66.111.4.25]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jJkiG-0000Ju-Eo for psycopg@postgresql.org; Wed, 01 Apr 2020 21:15:57 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 963265C03D8; Wed, 1 Apr 2020 17:15:51 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Wed, 01 Apr 2020 17:15:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= subject:from:to:cc:references:message-id:date:mime-version :in-reply-to:content-type:content-transfer-encoding; s=fm2; bh=V o39/T4/RTfbIeqstZ0A0NFu0MybjwE3BBjg/UqKPDI=; b=rJIHVaKqsYdji471A tA2KR1ss5JSX7mp1eMVOiaDRTs/1x9M4QhrIutqWuoGZUyTWRzgoaOYHNYwka/wN F8/1JrPLZH7yiTQmQaRorPD4D6uLMr+oRZQ/tTRU/nte0EZp6FRrZkp8hsiLPDz7 QNrEg0Efl6I1nwLkD+AHcYYtYfkacbMilZd9OUBwqICNzg9BDgk+bTeX5r9Ubaxy cVqCqJLdRXuHQaBql+6f2GX+vi6Dg2kdXowXQ1KAvjpUjISUnzaprv70nMaC/QL5 LZJQhLcYzFJT6nS49p+/R182llybZ4bkXnhsj7j93u/rVkN+aoTnwBUUwV4TLJxs O4+Cw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=Vo39/T4/RTfbIeqstZ0A0NFu0MybjwE3BBjg/UqKP DI=; b=mEYAgBhva3FcgAdEyWEAW4ZCErTGHkQ9dNguRZVyO/mzinbNvlLjXfxwt pJMyMyTDX0mN1NcT6tdzicav+InMMdhnJ0I+JOjQzuuWx0kaaKetQEm6QBmt8+6j UmYAgcJ6Io/evSxPGlk9lfUpPXVH4liMGoU/CFpEQn5SqgwYMXD5MoCLCKLc5t2O bMRQ1VjNo2B+07imTvZIKTYw62LiuTCxmip++LXJ75KJxVWXU8LFgX3VB5KPF8VV 3w7o1sbfF1wyeVA94s8fr8IB1FhkxWquhWr3QZVu+NHGEH2tE1lgg0JcfjFf88c/ k5qBsiWmZ6Qk6l9ICC4rvTHdS6x4g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrtddvgdduheekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepuffhvfhfkffffgggjggtgfesthekredttdefjeenucfhrhhomheptegurhhi rghnucfmlhgrvhgvrhcuoegrughrihgrnhdrkhhlrghvvghrsegrkhhlrghvvghrrdgtoh hmqeenucfkphepjeehrddujedvrdeltddrledvnecuvehluhhsthgvrhfuihiivgeptden ucfrrghrrghmpehmrghilhhfrhhomheprggurhhirghnrdhklhgrvhgvrhesrghklhgrvh gvrhdrtghomh X-ME-Proxy: Received: from [192.168.1.10] (75-172-90-92.tukw.qwest.net [75.172.90.92]) by mail.messagingengine.com (Postfix) with ESMTPA id AE85E306CD40; Wed, 1 Apr 2020 17:15:50 -0400 (EDT) Subject: Re: Inserting default values into execute_values From: Adrian Klaver To: Stephen Lagree Cc: Daniele Varrazzo , psycopg@postgresql.org References: <6db34cfa-c531-18ff-4368-bea8c171f6db@aklaver.com> <3cdc3522-f09a-529a-e329-b50418fb4172@aklaver.com> <0f255c7c-0eb0-fbfa-8c47-029f98b9a4f2@aklaver.com> Message-ID: Date: Wed, 1 Apr 2020 14:15:49 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.6.0 MIME-Version: 1.0 In-Reply-To: <0f255c7c-0eb0-fbfa-8c47-029f98b9a4f2@aklaver.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 4/1/20 2:04 PM, Adrian Klaver wrote: > On 4/1/20 1:31 PM, Stephen Lagree wrote: >> Thanks Daniele and Adrian, your answers were really helpful! >> >> Daniele, you are right, it is a waste sending long strings when I am >> just trying to generate entries in the sequence. >> I do want to do it in one shot so your generate_series suggestion >> should be great >>      insert into testins (id) select nextval('testins_id_seq') from >> generate_series(1, 10); >> >> However, I was playing around with the sql.Default and Adrian's >> Default class and couldn't get them to work with execute_values.  I >> know in my case it might not make sense to use a Default literal if >> that is all that is being added, but it might make sense for a query >> that sometimes is used for inserting DEFAULT and sometimes to insert a >> value. >> >>              query2 = "INSERT INTO MYTABLE (id) VALUES %s RETURNING id;" >>              args_list = [sql.DEFAULT, sql.DEFAULT] >>              execute_values(cursor, query2, args_list, >>                             template=None, page_size=100, fetch=True) >> >> There is a TypeError in execute_values for both Adrian's Default and >> sql.Default: >> >>              for page in _paginate(argslist, page_size=page_size): >>                  if template is None: >>      >               template = b'(' + b','.join([b'%s'] * >> len(page[0])) + b')' >>      E               TypeError: object of type 'SQL' has no len() >> >>      ../../.con >> da/envs/stbase/lib/python3.7/site-packages/psycopg2/extras.py:1275: >> TypeError >> >> I added a len and slicing function to Adrian's default class and tried >> it, but it then had an error with the mogrify line in execute values. >> I tried a few variations of templates with and without parentheses and >> that didn't work either. > > The DEFAULT and sql.SQL("DEFAULT") both return objects that do not play > well with the template as you found out. Not concentrating, the above is not correct for the DEFAULT case: class Default(object): """Set up DEFAULT value for a field. When doing INSERT or UPDATE in Postgres one can use DEFAULT/default as the value to have the server use the default set on the field. The below allows for doing that. """ def __conform__(self, proto): if proto is psycopg2.extensions.ISQLQuote: return self def getquoted(self): return 'DEFAULT' DEFAULT = Default() args_list = [(DEFAULT, DEFAULT)] execute_values(cur, query2, args_list, template=None, page_size=100, fetch=True) [(6,)] select * from t2; id | name ----+------- 1 | test 2 | test2 3 | name 4 | name 5 | name 6 | name What we both forgot is that args_list needs to a sequence of sequences. > > The simplest way I found is to do: > > query2 = "INSERT INTO t2 (id, name) VALUES %s RETURNING id;" > > execute_values(cur, query2, args_list, template="(DEFAULT, DEFAULT)", > page_size=100, fetch=True) > > [(3,), (4,)] > > test=# alter table t2 alter COLUMN name set default 'name'; > ALTER TABLE > test=# select * from t2; >  id | name > ----+------- >   1 | test >   2 | test2 > (2 rows) > > test=# select * from t2; >  id | name > ----+------- >   1 | test >   2 | test2 >   3 | name >   4 | name > (4 rows) > > > > > >> -- Adrian Klaver adrian.klaver@aklaver.com