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 1krRlx-0003OG-3N for psycopg@arkaria.postgresql.org; Mon, 21 Dec 2020 20:27:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1krRlw-00035z-1O for psycopg@arkaria.postgresql.org; Mon, 21 Dec 2020 20:27:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1krRlv-00035s-SC for psycopg@lists.postgresql.org; Mon, 21 Dec 2020 20:27:11 +0000 Received: from mail-lf1-x133.google.com ([2a00:1450:4864:20::133]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1krRlt-0003IU-IK for psycopg@postgresql.org; Mon, 21 Dec 2020 20:27:11 +0000 Received: by mail-lf1-x133.google.com with SMTP id a12so26743100lfl.6 for ; Mon, 21 Dec 2020 12:27:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=EYNqy8MF+UUf9q0x+TGlCRjDSCoNpefyzjvurNd1mSo=; b=qt52tuKYKXYJE8nRMDKGKUC5UPEBpYBEP7C1Hdb7nQksPzKlvsK+OxFL4/a5relv8d QYLclxtK61iUKbqQG0sjbYPKXEnHyKPJCJwfypYF/0dmXUWQ7EAXhwiDbm5IKQWAZopI rltB+R7BXKognf6jDs9YeeTxEx9dAK621k7a96Bk0BgF75TmHn+lOW2GPZvx8PzGh/07 Y2lj60MdX2vdtxd91vnCG5b9J0coCnSBuRNhEZoUyo1Zwq2Wit8l3hMXb12mFzT0jkpd 943syycaKmGXelY9N2IUx4I1/MkY96CT/kajtlqY3C4B8ay493fSVEdSlIBCq5mZtUav ihQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=EYNqy8MF+UUf9q0x+TGlCRjDSCoNpefyzjvurNd1mSo=; b=I2lUlGXZ+m6FHUDeXAEN1leCaaCOR36rCV2PnjlrB5PapOU18e7Rf2e9bc0L9xYX4s SJ79KBJQ7M+Apd6vO8u4Y41fS9c3Wwil3Emcx3oiR+AFxtpHNcjs9gggQD9KUkeyL8Hm SXa9jzVw0J3KQ2+LFzdEoMhCLsvw4iefEuthO4tzYCj63oF28LZ5SoYGxKnP41L3dq4l ETwIby8wgkBxqy77Ofdh/LaqaShW2n8obXRVka82qKvXTSGLUIB/tSVG3SVcCn/v7uPH NaqoF6j+V8T2ehB034OXHtPCWEP/sOSSUKS9fyGUiY5P5FDh6euVBeWAl7ybm/RKnXQC QNkA== X-Gm-Message-State: AOAM5316b2J+3MISbeSYxI1rgnhWBDQ/Sc8q6Os9YaNuPp8vlsHC853H gPcOnOKpsKT0cQ5NgCaYhUlZqdkLS+htsgW8/5KHKg3Dy3IW9Q== X-Google-Smtp-Source: ABdhPJwQWeX1EnqaojPUbhu9l5Zcvax24niXw4s6bsLpNywLnHWMXdK20VXtrNqgusvZBrDedV/1mTS6I/SVtTbVxjY= X-Received: by 2002:a19:8a46:: with SMTP id m67mr7271020lfd.515.1608582429057; Mon, 21 Dec 2020 12:27:09 -0800 (PST) MIME-Version: 1.0 References: <25a137a0-9ad3-bb9f-b008-263dcc81a645@aklaver.com> In-Reply-To: <25a137a0-9ad3-bb9f-b008-263dcc81a645@aklaver.com> From: Daniele Varrazzo Date: Mon, 21 Dec 2020 20:26:57 +0000 Message-ID: Subject: Re: psycopg3, prepared statements To: Adrian Klaver Cc: psycopg@postgresql.org Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Mon, 21 Dec 2020 at 16:02, Adrian Klaver wrote: > So your plan from [1] was like that in plpythonu where the process is > broken down into two parts. Is there anything useful to learn from the plpythonu experience? I'm not very familiar with it. > What I'm not following is whether that is > still the plan or whether prepare/execute is going to happen without the > cursor.prepare() and just be automatic on cursor.execute()? With the > provision to override per cursor. I would do without `cursor.prepare(query)`. As a starter it should be `cursor.prepare(query, args)` in order to sniff the types, so you would also need to pass it a sample of data (or the types). So now 1) as interface it's very similar to `cursor.execute(query, args)`, but it would prepare and not run the query, and 2) it's a moment in your program's lifetime where you know the query to run and the arguments: most likely now you want to run the query too, not only to prepare it. So the lack of a function "prepare the query, with these types, but don't run it" doesn't seem a very likely one. I am also assuming that, if the assumption is that "preparing queries is good", it would be better to let it happen automatically instead of asking the people to do it on their own. Does it make sense? ---- I mistakenly replied Adrian privately. Following, his reply. On Mon, 21 Dec 2020 at 16:45, Adrian Klaver wrote: > Is there anything useful to learn from the plpythonu experience? I'm > not very familiar with it. The user visible portion can be found here: https://www.postgresql.org/docs/current/plpython-database.html The most notable part is that it requires type definition(s) for parameters in the prepare portion. That and a prepared query can be passed around to different execute and different function calls. > I would do without `cursor.prepare(query)`. [...] If I read the above correctly this boils down to cursor.execute(query, args) will always be prepared once the connection.prepare_threshold(default 5)is passed and evicted after connection.prepared_number(default 100) other queries are run. > Does it make sense? I think so. Personally, I prefer the two step approach as I am becoming less and less enthusiastic about hidden 'magic'. To that end a global(maybe connection) setting that would disable prepare would be nice. ---- To which, 1) thank you very much, Adrian, for the plpython pointer, I'll take a look at it. 2) About disabling the automatic prepare: the mechanism I have in mind is to set prepare_threshold to None on the connection instance; however we could make sure to have the default attribute defined on the class: this way who really hates the idea of prepared statements can be cheeky and set `psycopg3.Connection.prepare_threshold = None` instead of `myconn.prepare_threshold`... More seriously, if there is a large base of people who think that something can go wrong with prepared statement we can either provide a better interface to control it globally or to have the feature opt-in. -- Daniele