{"body":"cur = <cursor object at 0x7f83adc48520; closed: -1>\nsql = b'INSERT INTO listen (listened_at, track_name, user_name, data)\\n                    VALUES %s\\n                    ON..., user_name)\\n                        DO NOTHING\\n                        RETURNING listened_at, track_name, user_name'\nargslist = [(1400000000, 'Immigrant Song 0', 'test', '{\"user_id\":1,\"track_metadata\":{\"additional_info\":{\"recording_mbid\":\"2cfad20...40dc151\",\"release_msid\":null,\"recording_msid\":\"4269ddbc-9241-46da-935d-4fa9e0f7f371\"},\"artist_name\":\"Led Zeppelin\"}}')]\ntemplate = b'(%s,%s,%s,%s)', page_size = 100, fetch = False\n\n    def execute_values(cur, sql, argslist, template=None, page_size=100, fetch=False):\n        '''Execute a statement using :sql:`VALUES` with a sequence of parameters.\n    \n        :param cur: the cursor to use to execute the query.\n    \n        :param sql: the query to execute. It must contain a single ``%s``\n            placeholder, which will be replaced by a `VALUES list`__.\n            Example: ``\"INSERT INTO mytable (id, f1, f2) VALUES %s\"``.\n    \n        :param argslist: sequence of sequences or dictionaries with the arguments\n            to send to the query. The type and content must be consistent with\n            *template*.\n    \n        :param template: the snippet to merge to every item in *argslist* to\n            compose the query.\n    \n            - If the *argslist* items are sequences it should contain positional\n              placeholders (e.g. ``\"(%s, %s, %s)\"``, or ``\"(%s, %s, 42)``\" if there\n              are constants value...).\n    \n            - If the *argslist* items are mappings it should contain named\n              placeholders (e.g. ``\"(%(id)s, %(f1)s, 42)\"``).\n    \n            If not specified, assume the arguments are sequence and use a simple\n            positional template (i.e.  ``(%s, %s, ...)``), with the number of\n            placeholders sniffed by the first element in *argslist*.\n    \n        :param page_size: maximum number of *argslist* items to include in every\n            statement. If there are more items the function will execute more than\n            one statement.\n    \n        :param fetch: if `!True` return the query results into a list (like in a\n            `~cursor.fetchall()`).  Useful for queries with :sql:`RETURNING`\n            clause.\n    \n        .. __: https://www.postgresql.org/docs/current/static/queries-values.html\n    \n        After the execution of the function the `cursor.rowcount` property will\n        **not** contain a total result.\n    \n        While :sql:`INSERT` is an obvious candidate for this function it is\n        possible to use it with other statements, for example::\n    \n            >>> cur.execute(\n            ... \"create table test (id int primary key, v1 int, v2 int)\")\n    \n            >>> execute_values(cur,\n            ... \"INSERT INTO test (id, v1, v2) VALUES %s\",\n            ... [(1, 2, 3), (4, 5, 6), (7, 8, 9)])\n    \n            >>> execute_values(cur,\n            ... \"\"\"UPDATE test SET v1 = data.v1 FROM (VALUES %s) AS data (id, v1)\n            ... WHERE test.id = data.id\"\"\",\n            ... [(1, 20), (4, 50)])\n    \n            >>> cur.execute(\"select * from test order by id\")\n            >>> cur.fetchall()\n            [(1, 20, 3), (4, 50, 6), (7, 8, 9)])\n    \n        '''\n        from psycopg2.sql import Composable\n        if isinstance(sql, Composable):\n            sql = sql.as_string(cur)\n    \n        # we can't just use sql % vals because vals is bytes: if sql is bytes\n        # there will be some decoding error because of stupid codec used, and Py3\n        # doesn't implement % on bytes.\n        if not isinstance(sql, bytes):\n            sql = sql.encode(_ext.encodings[cur.connection.encoding])\n        pre, post = _split_sql(sql)\n    \n        result = [] if fetch else None\n        for page in _paginate(argslist, page_size=page_size):\n            if template is None:\n                template = b'(' + b','.join([b'%s'] * len(page[0])) + b')'\n            parts = pre[:]\n            for args in page:\n                parts.append(cur.mogrify(template, args))\n                parts.append(b',')\n            parts[-1:] = post\n>           cur.execute(b''.join(parts))\nE           psycopg2.errors.InsufficientPrivilege: permission denied for table listen","name":"","extension":"txt","url":"https://www.irccloud.com/pastebin/Q9HUPkiT","modified":1591441574,"id":"Q9HUPkiT","size":4306,"lines":87,"own_paste":false,"theme":"","date":1591441574}