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 1kkSci-0004OZ-5P for psycopg@arkaria.postgresql.org; Wed, 02 Dec 2020 13:56:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kkScg-0001NH-Tv for psycopg@arkaria.postgresql.org; Wed, 02 Dec 2020 13:56:46 +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 1kkScg-0001NA-Lz for psycopg@lists.postgresql.org; Wed, 02 Dec 2020 13:56:46 +0000 Received: from mail-lf1-x136.google.com ([2a00:1450:4864:20::136]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kkSce-0002hq-6l for psycopg@postgresql.org; Wed, 02 Dec 2020 13:56:46 +0000 Received: by mail-lf1-x136.google.com with SMTP id j205so4874592lfj.6 for ; Wed, 02 Dec 2020 05:56:43 -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=M6by5uhVdeufIYH/boNt/eOyLo9EciOxbPnfdJbKVB4=; b=sv8Jwi6gsHEgp+7JGdkhcNHzxoTcftQTb79lW7EDTJ8vltyu5gSHo7TB2M+2/a4Tl8 ffWIlDm0gP3lJoWTSeDoORrUKKFf+/4ZupbnQsxIZf+mQOHByazPHsxpJZl2O5HppAk7 BsKgWWRj5WF6aiz5+JG4GghIhmWMyWfGH3OjVHOt+EMUvQjJuQqStfIpVw6y3eE/8BRL P5ZFZepWvZbkdkbG3Q70Kn90zEcFFBYgmOIPd5xbWP6eYVUH69jvwDX0bpEveY7R5sc8 370MmGSM3x3C7Q/1splP7tIPfJM3QIxfxt5ezrCdi5dLcp2yYe4vdlVsPqx3BPNcJEqU RTCw== 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=M6by5uhVdeufIYH/boNt/eOyLo9EciOxbPnfdJbKVB4=; b=coZ84SKSNo1725fMgkiMK/fQve0h8nIz3ptIHCWABBRpf1osxxvoXTaGaQLG9kcZhk jSWOjyR3KrugbZBD7vmxoPatePj4OgGANHGGK788R/R7c9+7RDt8Zhc69G0jjrfZi6MJ YYuxCyXlsbiGUoXpKDVyK6DVLfd5Niwl5R4WmXJvg3dd0hht28wz6G7FAbPWmT6QDagz 2LzV5/a9Tu6SJmUvS5N4oQ9q4J3AfLhMftWNDtVxWHJ9uVXzJmHy9bIfvNuRmtJKau25 iuzZsQV8sGL+NRmiDkf2X5GP95VFS4KYD6hDG+0lttjhaxUjA31mvwYHwDqkSxfMawRm oe0w== X-Gm-Message-State: AOAM530CnxlXwT7NsxQ/lhYNM4z5NoT8JetdN8AXPPcU3yVldbbg51ox b7XnaOoKGPZEG1auBk52JQRNMwNmsmhqhxVIr34r/bUQQzU= X-Google-Smtp-Source: ABdhPJwHN1tSD/m5DCqGDAvJ37MiIsQyjoolD+d9ltNNwcfnJmlQThZsg0o6s2pXzFYFG0HwHTojk6JAnRWNyapAW8I= X-Received: by 2002:a19:2489:: with SMTP id k131mr1250391lfk.459.1606917402895; Wed, 02 Dec 2020 05:56:42 -0800 (PST) MIME-Version: 1.0 References: <20201202124807.GA21315@campbell-lange.net> In-Reply-To: <20201202124807.GA21315@campbell-lange.net> From: Daniele Varrazzo Date: Wed, 2 Dec 2020 13:56:31 +0000 Message-ID: Subject: Re: Executing on the connection? To: Rory Campbell-Lange 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 Wed, 2 Dec 2020 at 12:48, Rory Campbell-Lange wrote: > The only issue I see with this sort of approach is the problem of having > to set the search path, which I believe needs to be done for each > cursor where custom search paths are used. No, being the search path a property of the session, it is a property of the connection, and all the cursors on the same connection will share the same. The use case suggested is only for the barebone use of connection + cursor + execute + fetch. I wouldn't advise it as the most generic usage, only as a shortcut. > > ...actually there will be no callproc at all in > > psycopg3... > Ah. We presently use callproc a lot, together with NamedTupleConnection, > which works brilliantly for us. The problem with callproc is that it has a confusing semantic in itself: from the DBAPI : """ The result of the call is returned as modified copy of the input sequence. Input parameters are left untouched, output and input/output parameters replaced with possibly new values. """ which 1) is silly unless you are writing C, 2) in postgres you don't know if the params are I/O unless you do extra query to query the catalog. Maybe it's modelled after databases using this precise same interface, but postgres doesn't. On top of that, Postgres also provides named parameters, which are supported in psycopg2, and were in psycopg3. You can see how sprawling it was to convert named and positional parameters from this commit, where I finally pulled out the plug . On top of on the top of that, recent PostgreSQL added a new concept of procedure, different from what is called stored procedure, and which require CALL instead of SELECT: Again, without knowing the catalog, you cannot tell by name which is which, but people would expect us to know: . If you know which parameters are positional and which are named, if you know whether a stored procedure is a function or a new procedure, users can just use cursor.execute(): it will be faster than composing SQL dynamically. Using the newly available fetch*() chaining you can get results directly from the call, which in psycopg2 needs two lines of code: result = cur.execute("SELECT my_function(%s, 42, foo=%s)", ["bar", baz]).fetchone() This is pretty much the most efficient thing that can be done (bar making it a prepared statement), because the libpq/postgres don't offer any fast-path for function calls. There is this , but it's deprecatish, non-feature-complete, and requires a pg_catalog lookup to find the function oid. Hope this explains the rationale behind dropping callproc (which is an optional method of the DBAPI so it doesn't make us less standard-compliant by not implementing it). Feedback is welcome anyway :) Cheers, -- Daniele