Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1geeFe-0002D7-8d for pgadmin-hackers@arkaria.postgresql.org; Wed, 02 Jan 2019 10:59:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1geeFc-0007OG-UC for pgadmin-hackers@arkaria.postgresql.org; Wed, 02 Jan 2019 10:59:52 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1geeFc-0007KI-G1 for pgadmin-hackers@lists.postgresql.org; Wed, 02 Jan 2019 10:59:52 +0000 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1geeFY-00010G-4x for pgadmin-hackers@postgresql.org; Wed, 02 Jan 2019 10:59:52 +0000 Received: by mail-ed1-x533.google.com with SMTP id h50so25840940ede.5 for ; Wed, 02 Jan 2019 02:59:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=wl7e4VdJX+n6FxyB80JmE3IB72R30uLB54LpoxA+8jo=; b=xhV+OnIMlyx8er6XKowFTjNP4M2ALh0JMJeYS7PWlWLCBJcuWUY0halY3h/K1/+pOz U71Kbhhv+vxaLs1XDf8hbqWn2tcraz+I0odrbzna4uPGIxhMS/ZL2d5fyteLWFG4+5Sw dQB0xMd6eA01vgcvohAp4tlAzKdNnvQTxeFWTrf4eE94wro03ZlL5SnvDrFU7nfQ7zH8 d5JlplZHZ0XbAZhrwQr/lPwgyBQNqoCjF5Klo/22g+wdJrt7gvgw0HE7ccM/hb20B+vR gVDAgCOzYmCps25K9R6IHEHkSfG29LWLIcOXsATvygtmHT1iVg45Qt1Sx0oG8gS8Pfjc i1uA== 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=wl7e4VdJX+n6FxyB80JmE3IB72R30uLB54LpoxA+8jo=; b=eEeRcI2J5zFnk8WJZxireBBc74ToZh4e/YAIi37nTVfSEZh+o5RvJZWyzuCmqxe6cm bLP0oUyA1F9hEM8mm2tly0MDjmz5QaUcm7JeETJV4hfefYZrhrsEgSWwHFK0OhQfkUs6 x8fq1ECvm38dIh96c8d54ff36NbULvtxVxsAw9yCUBdBUM0xfM5lPBIJWUi48bx57naX /Ufan/y75/MsGOvWi/sWPM5Ifho/HvKR2nbpkFn+SvAcTm7gtgw1hvIDu3GoXubdOIBF 4eQuZxp82jIb6R9xTbFNvS1vaonrQ0krHrAsGSOPyJGzoALP/R0TzSyRwVnrHzfHFQ0E XK9A== X-Gm-Message-State: AA+aEWYdhsxYRBrkX9WBndOcEy6560kK8WN9WAvINy3Jk2Dg8Ta7yAw6 /VBy6qgx9GQqig8XYCUs7jorW4ibtLGO8x7bZdcEu0x4aTSu0cKyaH/tGJ9Y3g7JBKx2RhD6FMa 1oELhT/d7+TgdLTvpo609HDmVoJUf0H2sJHcrgOiEWj0ABajBtBBx+GsphsiA1kBzFvYtPijjGD IaQdAiJc5S+ls= X-Google-Smtp-Source: AFSGD/XQnRSwLm16B2NvVDaZPzxF/scKNNJq4iq92jko7GHMmBe3922KvwOJssOImJ5wWlE2KIXvlg== X-Received: by 2002:a17:906:e1d0:: with SMTP id gp16-v6mr33099414ejb.221.1546426785854; Wed, 02 Jan 2019 02:59:45 -0800 (PST) Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com. [209.85.128.51]) by smtp.gmail.com with ESMTPSA id i46sm20920567ede.62.2019.01.02.02.59.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Jan 2019 02:59:44 -0800 (PST) Received: by mail-wm1-f51.google.com with SMTP id f188so27256221wmf.5 for ; Wed, 02 Jan 2019 02:59:44 -0800 (PST) X-Received: by 2002:a1c:910e:: with SMTP id t14mr22248351wmd.111.1546426784136; Wed, 02 Jan 2019 02:59:44 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Dave Page Date: Wed, 2 Jan 2019 10:59:32 +0000 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [pgAdmin4][Patch] - RM 3780 pgAdmin4 lacks ability to specify NULL values in CSV export To: Akshay Joshi Cc: pgadmin-hackers Content-Type: multipart/alternative; boundary="00000000000023da64057e778b5b" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --00000000000023da64057e778b5b Content-Type: text/plain; charset="UTF-8" On Tue, Jan 1, 2019 at 9:48 AM Akshay Joshi wrote: > Hi Dave/Hackers > > On Mon, Dec 24, 2018 at 7:47 AM Akshay Joshi .com> wrote: > >> >> >> On Fri, 21 Dec 2018, 19:45 Dave Page > >>> >>> >>> On Fri, Dec 21, 2018 at 2:08 PM Akshay Joshi < >>> akshay.joshi@enterprisedb.com> wrote: >>> >>>> >>>> >>>> On Fri, 21 Dec 2018, 18:52 Dave Page >>> >>>>> Hi >>>>> >>>>> Looks good - I just found one issue; please go ahead and commit (with >>>>> a release notes update) when fixed. >>>>> >>>>> - If I set the NULL replacement value to an empty string, it defaults >>>>> back to NULL. It's therefore not possible to replace null values with an >>>>> empty value. >>>>> >>>> >>>> If you remember this is the default behaviour of the Preferences >>>> dialog. It sets the default value again if you set the blank value. Fahar >>>> has raised the same issue before and we have rejected that. If you think we >>>> can create the new RM for that behaviour and will commit the current patch. >>>> >>> >>> Well, we rejected it for a specific case. In this specific case, it >>> makes sense to be able to enter a blank value. >>> >>> Maybe we just need an "allow blank" flag on the preference object, that >>> does nothing except allow you to remove the default (or any other) value >>> without it being replaced again? Obviously the default still needs to work >>> until a value is written to the config DB. >>> >> >> Ok. If i understand correctly this new parameter works for all the >> preference parameter if set to true. By default it's value is False and if >> user wants to enter blank value they will ser the flag. >> > > I think we should not add new preferences flag "allow blank". > Meanwhile I have added new parameter "allow_blank" to the register function > for preferences, so at the time of registering the preference we can set > the value of "allow_blank" parameter, if blank value is acceptable. I have > committed my patch with this changes. > > If you think we need that flag as a Preferences object then I'll > create a new RM for it. > It sounds like you've committed what I just described in my previous message :-) > >>> >>>> >>>>> Thanks! >>>>> >>>>> On Fri, Dec 21, 2018 at 12:57 PM Akshay Joshi < >>>>> akshay.joshi@enterprisedb.com> wrote: >>>>> >>>>>> Hi Dave >>>>>> >>>>>> I have modified the condition, it won't through any exception. >>>>>> Attached is the updated patch, please review it. >>>>>> >>>>>> On Fri, Dec 21, 2018 at 4:22 AM Dave Page wrote: >>>>>> >>>>>>> Sorry! Here is is. >>>>>>> >>>>>>> On Fri, Dec 21, 2018 at 12:12 PM Akshay Joshi < >>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>> >>>>>>>> Hi Dave >>>>>>>> >>>>>>>> Can you please attached the updated patch with your changes. I'll >>>>>>>> try to fix the exception. >>>>>>>> >>>>>>>> On Fri, Dec 21, 2018 at 3:57 AM Dave Page >>>>>>>> wrote: >>>>>>>> >>>>>>>>> Hi >>>>>>>>> >>>>>>>>> Here's an updated patch as I've tweaked some of the wording. The >>>>>>>>> screenshot probably isn't the right resolution, but as we're replacing them >>>>>>>>> anyway it doesn't seem overly important. Feel free to fix if you like :-) >>>>>>>>> >>>>>>>>> With quoting set to either All or Strings, everything looks good. >>>>>>>>> With it set to None, I still get an exception (below). The query I'm using >>>>>>>>> is this: >>>>>>>>> >>>>>>>>> SELECT NULL::text, 1234::int, 'Foo bar'::text, E'Foo\nBar'::text >>>>>>>>> >>>>>>>>> Field separator: , >>>>>>>>> Quote character: " >>>>>>>>> Replace null's with: NULL >>>>>>>>> >>>>>>>>> Steps: >>>>>>>>> >>>>>>>>> 1) Run pgAdmin in Desktop mode. I'm running from within PyuCharms, >>>>>>>>> using the venv detailed below. >>>>>>>>> 2) Open the Query Tool on a PostgreSQL 9.6.10 database, running on >>>>>>>>> MacOS 10.14.1 >>>>>>>>> 3) Run the above query, wit quoting set to All and check the >>>>>>>>> result in the grid. >>>>>>>>> 4) Download the CSV file and check. >>>>>>>>> 5) Open Preferences and set quoting to Strings. >>>>>>>>> 6) Download the CSV file and check. >>>>>>>>> 7) Open Preferences and set quoting to None. >>>>>>>>> 8) Download the CSV file *exception occurs*. >>>>>>>>> >>>>>>>>> >>>>>>>>> System info: >>>>>>>>> >>>>>>>>> (pgadmin4) dpage@hal:*~/git/pgadmin4*$ python --version >>>>>>>>> >>>>>>>>> Python 3.6.7 >>>>>>>>> >>>>>>>>> (pgadmin4) dpage@hal:*~/git/pgadmin4*$ pip freeze >>>>>>>>> >>>>>>>>> alabaster==0.7.11 >>>>>>>>> >>>>>>>>> alembic==1.0.0 >>>>>>>>> >>>>>>>>> asn1crypto==0.24.0 >>>>>>>>> >>>>>>>>> Babel==2.6.0 >>>>>>>>> >>>>>>>>> bcrypt==3.1.4 >>>>>>>>> >>>>>>>>> blinker==1.4 >>>>>>>>> >>>>>>>>> certifi==2018.8.24 >>>>>>>>> >>>>>>>>> cffi==1.11.5 >>>>>>>>> >>>>>>>>> chardet==3.0.4 >>>>>>>>> >>>>>>>>> chromedriver-installer==0.0.6 >>>>>>>>> >>>>>>>>> click==6.7 >>>>>>>>> >>>>>>>>> cryptography==2.3 >>>>>>>>> >>>>>>>>> docutils==0.14 >>>>>>>>> >>>>>>>>> extras==1.0.0 >>>>>>>>> >>>>>>>>> fixtures==3.0.0 >>>>>>>>> >>>>>>>>> Flask==0.12.4 >>>>>>>>> >>>>>>>>> Flask-BabelEx==0.9.3 >>>>>>>>> >>>>>>>>> Flask-Gravatar==0.5.0 >>>>>>>>> >>>>>>>>> Flask-HTMLmin==1.3.2 >>>>>>>>> >>>>>>>>> Flask-Login==0.3.2 >>>>>>>>> >>>>>>>>> Flask-Mail==0.9.1 >>>>>>>>> >>>>>>>>> Flask-Migrate==2.1.1 >>>>>>>>> >>>>>>>>> Flask-Paranoid==0.2.0 >>>>>>>>> >>>>>>>>> Flask-Principal==0.4.0 >>>>>>>>> >>>>>>>>> Flask-Security==3.0.0 >>>>>>>>> >>>>>>>>> Flask-SQLAlchemy==2.3.2 >>>>>>>>> >>>>>>>>> Flask-WTF==0.14.2 >>>>>>>>> >>>>>>>>> html5lib==1.0.1 >>>>>>>>> >>>>>>>>> htmlmin==0.1.12 >>>>>>>>> >>>>>>>>> idna==2.7 >>>>>>>>> >>>>>>>>> imagesize==1.1.0 >>>>>>>>> >>>>>>>>> itsdangerous==0.24 >>>>>>>>> >>>>>>>>> Jinja2==2.10 >>>>>>>>> >>>>>>>>> linecache2==1.0.0 >>>>>>>>> >>>>>>>>> Mako==1.0.7 >>>>>>>>> >>>>>>>>> MarkupSafe==1.0 >>>>>>>>> >>>>>>>>> packaging==18.0 >>>>>>>>> >>>>>>>>> paramiko==2.4.1 >>>>>>>>> >>>>>>>>> passlib==1.7.1 >>>>>>>>> >>>>>>>>> pbr==3.1.1 >>>>>>>>> >>>>>>>>> psutil==5.4.8 >>>>>>>>> >>>>>>>>> psycopg2==2.7.5 >>>>>>>>> >>>>>>>>> pyasn1==0.4.4 >>>>>>>>> >>>>>>>>> pycodestyle==2.3.1 >>>>>>>>> >>>>>>>>> pycparser==2.18 >>>>>>>>> >>>>>>>>> pycrypto==2.6.1 >>>>>>>>> >>>>>>>>> Pygments==2.2.0 >>>>>>>>> >>>>>>>>> PyNaCl==1.2.1 >>>>>>>>> >>>>>>>>> pyparsing==2.2.2 >>>>>>>>> >>>>>>>>> pyperclip==1.6.4 >>>>>>>>> >>>>>>>>> pyrsistent==0.14.2 >>>>>>>>> >>>>>>>>> python-dateutil==2.7.3 >>>>>>>>> >>>>>>>>> python-editor==1.0.3 >>>>>>>>> >>>>>>>>> python-mimeparse==1.6.0 >>>>>>>>> >>>>>>>>> pytz==2018.3 >>>>>>>>> >>>>>>>>> requests==2.19.1 >>>>>>>>> >>>>>>>>> selenium==3.14.1 >>>>>>>>> >>>>>>>>> simplejson==3.13.2 >>>>>>>>> >>>>>>>>> six==1.11.0 >>>>>>>>> >>>>>>>>> snowballstemmer==1.2.1 >>>>>>>>> >>>>>>>>> speaklater==1.3 >>>>>>>>> >>>>>>>>> Sphinx==1.8.2 >>>>>>>>> >>>>>>>>> sphinxcontrib-websupport==1.1.0 >>>>>>>>> >>>>>>>>> SQLAlchemy==1.2.10 >>>>>>>>> >>>>>>>>> sqlparse==0.2.4 >>>>>>>>> >>>>>>>>> sshtunnel==0.1.4 >>>>>>>>> >>>>>>>>> testscenarios==0.5.0 >>>>>>>>> >>>>>>>>> testtools==2.3.0 >>>>>>>>> >>>>>>>>> traceback2==1.4.0 >>>>>>>>> >>>>>>>>> unittest2==1.1.0 >>>>>>>>> >>>>>>>>> urllib3==1.23 >>>>>>>>> >>>>>>>>> webencodings==0.5.1 >>>>>>>>> >>>>>>>>> Werkzeug==0.14.1 >>>>>>>>> >>>>>>>>> WTForms==2.1 >>>>>>>>> >>>>>>>>> Exception: >>>>>>>>> >>>>>>>>> 2018-12-21 11:47:28,995: SQL pgadmin: Execute (with server >>>>>>>>> cursor) for server #2 - CONN:8760231 (Query-id: 8649354): >>>>>>>>> SELECT NULL::text, 1234::int, 'Foo bar'::text, E'Foo\nBar'::text >>>>>>>>> 2018-12-21 11:47:29,001: INFO werkzeug: 127.0.0.1 - - >>>>>>>>> [21/Dec/2018 11:47:29] "GET >>>>>>>>> /sqleditor/query_tool/download/2133388?query=SELECT%20NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%3A%3Atext%2C%20E%27Foo%5CnBar%27%3A%3Atext&filename=data-1545392848979.csv >>>>>>>>> HTTP/1.1" 500 - >>>>>>>>> 2018-12-21 11:47:29,003: ERROR werkzeug: Error on request: >>>>>>>>> Traceback (most recent call last): >>>>>>>>> File >>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", >>>>>>>>> line 270, in run_wsgi >>>>>>>>> execute(self.server.app) >>>>>>>>> File >>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", >>>>>>>>> line 260, in execute >>>>>>>>> for data in application_iter: >>>>>>>>> File >>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wsgi.py", >>>>>>>>> line 870, in __next__ >>>>>>>>> return self._next() >>>>>>>>> File >>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wrappers.py", >>>>>>>>> line 82, in _iter_encoded >>>>>>>>> for item in iterable: >>>>>>>>> File >>>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/utils/driver/psycopg2/connection.py", >>>>>>>>> line 848, in gen >>>>>>>>> csv_writer.writerows(results) >>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line >>>>>>>>> 761, in writerows >>>>>>>>> return self.writer.writerows(map(self._dict_to_list, rowdicts)) >>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line >>>>>>>>> 268, in writerows >>>>>>>>> self.writerow(row) >>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line >>>>>>>>> 261, in writerow >>>>>>>>> row = [self.strategy.prepare(field, only=only) for field in >>>>>>>>> row] >>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line >>>>>>>>> 261, in >>>>>>>>> row = [self.strategy.prepare(field, only=only) for field in >>>>>>>>> row] >>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line >>>>>>>>> 142, in prepare >>>>>>>>> raise Error('No escapechar is set') >>>>>>>>> _csv.Error: No escapechar is set >>>>>>>>> >>>>>>>>> On Thu, Dec 20, 2018 at 1:05 PM Akshay Joshi < >>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>> >>>>>>>>>> Hi Dave >>>>>>>>>> >>>>>>>>>> On Thu, Dec 20, 2018 at 5:12 PM Akshay Joshi < >>>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, Dec 20, 2018 at 4:48 PM Dave Page >>>>>>>>>>> wrote: >>>>>>>>>>> >>>>>>>>>>>> Hi >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Dec 20, 2018 at 10:09 AM Akshay Joshi < >>>>>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi Dave >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, Dec 20, 2018 at 3:08 PM Dave Page >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>> When testing with quoting set to None, quote = " and >>>>>>>>>>>>>> delimiter = , I get the following exception when I try to download: >>>>>>>>>>>>>> >>>>>>>>>>>>>> 2018-12-20 09:34:02,547: SQL pgadmin: Execute (with server >>>>>>>>>>>>>> cursor) for server #2 - CONN:354106 (Query-id: 4121147): >>>>>>>>>>>>>> SELECT NULL::text, 1234::int, 'Foo bar'::text, >>>>>>>>>>>>>> E'Foo\nBar'::text >>>>>>>>>>>>>> 2018-12-20 09:34:02,570: INFO werkzeug: 127.0.0.1 - - >>>>>>>>>>>>>> [20/Dec/2018 09:34:02] "GET >>>>>>>>>>>>>> /sqleditor/query_tool/download/5610522?query=SELECT%20NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%3A%3Atext%2C%20E%27Foo%5CnBar%27%3A%3Atext&filename=data-1545298442530.csv >>>>>>>>>>>>>> HTTP/1.1" 500 - >>>>>>>>>>>>>> 2018-12-20 09:34:02,572: ERROR werkzeug: Error on request: >>>>>>>>>>>>>> Traceback (most recent call last): >>>>>>>>>>>>>> File >>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", >>>>>>>>>>>>>> line 270, in run_wsgi >>>>>>>>>>>>>> execute(self.server.app) >>>>>>>>>>>>>> File >>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", >>>>>>>>>>>>>> line 260, in execute >>>>>>>>>>>>>> for data in application_iter: >>>>>>>>>>>>>> File >>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wsgi.py", >>>>>>>>>>>>>> line 870, in __next__ >>>>>>>>>>>>>> return self._next() >>>>>>>>>>>>>> File >>>>>>>>>>>>>> "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wrappers.py", >>>>>>>>>>>>>> line 82, in _iter_encoded >>>>>>>>>>>>>> for item in iterable: >>>>>>>>>>>>>> File >>>>>>>>>>>>>> "/Users/dpage/git/pgadmin4/web/pgadmin/utils/driver/psycopg2/connection.py", >>>>>>>>>>>>>> line 820, in gen >>>>>>>>>>>>>> csv_writer.writerows(results) >>>>>>>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", >>>>>>>>>>>>>> line 748, in writerows >>>>>>>>>>>>>> return self.writer.writerows(map(self._dict_to_list, >>>>>>>>>>>>>> rowdicts)) >>>>>>>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", >>>>>>>>>>>>>> line 256, in writerows >>>>>>>>>>>>>> self.writerow(row) >>>>>>>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", >>>>>>>>>>>>>> line 249, in writerow >>>>>>>>>>>>>> row = [self.strategy.prepare(field, only=only) for field >>>>>>>>>>>>>> in row] >>>>>>>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", >>>>>>>>>>>>>> line 249, in >>>>>>>>>>>>>> row = [self.strategy.prepare(field, only=only) for field >>>>>>>>>>>>>> in row] >>>>>>>>>>>>>> File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", >>>>>>>>>>>>>> line 136, in prepare >>>>>>>>>>>>>> raise Error('No escapechar is set') >>>>>>>>>>>>>> _csv.Error: No escapechar is set >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> Not able to reproduce the above issue. I have tested it >>>>>>>>>>>>> with the same setting as you mentioned. Please refer all the attached >>>>>>>>>>>>> screenshots. Please specify the steps if they are different. >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> When I have quoting set to All, the first column is returned >>>>>>>>>>>>>> as "" >>>>>>>>>>>>>> >>>>>>>>>>>>>> dpage@hal:*~/Downloads*$ more data-1545298598112.csv >>>>>>>>>>>>>> >>>>>>>>>>>>>> "text","int4","text-2","text-3" >>>>>>>>>>>>>> >>>>>>>>>>>>>> "","1234","Foo bar","Foo >>>>>>>>>>>>>> >>>>>>>>>>>>>> Bar" >>>>>>>>>>>>>> >>>>>>>>>>>>>> Isn't the point for it to be NULL? >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> while quoting is set to ALL, all the data types has been >>>>>>>>>>>>> quoted, so I thought null values should be replaced by "" instead of blank. >>>>>>>>>>>>> But if you think null values shouldn't be quoted even if user select quote >>>>>>>>>>>>> ALL, I'll fix it and resend the patch. >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> So how would you distinguish NULL from an empty string? Isn't >>>>>>>>>>>> that exactly what the bug is about? >>>>>>>>>>>> >>>>>>>>>>>> I still think we need a "Replace NULLs with" config option, and >>>>>>>>>>>> regardless of quoting settings we always replace NULL values with whatever >>>>>>>>>>>> that is set to - for which the user could then choose options like: >>>>>>>>>>>> >>>>>>>>>>>> NULL >>>>>>>>>>>> "NULL" >>>>>>>>>>>> "" >>>>>>>>>>>> '' >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> We would never quote the NULL replacement value - if the user >>>>>>>>>>>> wanted it to be quoted, they would include the quotes in the configured >>>>>>>>>>>> string. >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> OK, Will work on it and send the modified patch again. >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> Attached is the modified patch as per your suggestion. >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> On Tue, Dec 18, 2018 at 11:13 AM Akshay Joshi < >>>>>>>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Dave >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Attached is the modified patch to fix review comments. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Tue, Dec 18, 2018 at 3:00 PM Akshay Joshi < >>>>>>>>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Tue, Dec 18, 2018 at 2:49 PM Dave Page < >>>>>>>>>>>>>>>> dpage@pgadmin.org> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Tue, Dec 18, 2018 at 3:45 AM Akshay Joshi < >>>>>>>>>>>>>>>>> akshay.joshi@enterprisedb.com> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Hackers, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Attached is the patch to fix RM #3780 pgAdmin4 lacks >>>>>>>>>>>>>>>>>> ability to specify NULL values in CSV export. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Please review it. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> A few points; >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - You've included code from backports.csv, but per the >>>>>>>>>>>>>>>>> licence you need to include a description of the changes made. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Sure. In that case I'll copy the complete file and >>>>>>>>>>>>>>>> will do my changes which is of two lines only. With my patch I have remove >>>>>>>>>>>>>>>> all the unwanted code from backport.csv. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - Shouldn't backports.csv be removed from >>>>>>>>>>>>>>>>> requirements.txt, or is it used elsewhere? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Yes. Will do that. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - If the previous point is true, then I'm fairly sure >>>>>>>>>>>>>>>>> there is code in one or more of the many package build scripts that adds an >>>>>>>>>>>>>>>>> __init__.py file to backports.csv in the venv that's created. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> I'll remove that code as well. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>>>>> Blog: http://pgsnake.blogspot.com >>>>>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>>>>>>>>>>>>>> The Enterprise PostgreSQL Company >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *Sr. Software Architect * >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *Sr. Software Architect * >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> -- >>>>>>>>>>>>>> Dave Page >>>>>>>>>>>>>> Blog: http://pgsnake.blogspot.com >>>>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>>>> >>>>>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>>>>>>>>>>> The Enterprise PostgreSQL Company >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> -- >>>>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>>>> >>>>>>>>>>>>> *Sr. Software Architect * >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Dave Page >>>>>>>>>>>> Blog: http://pgsnake.blogspot.com >>>>>>>>>>>> Twitter: @pgsnake >>>>>>>>>>>> >>>>>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>>>>>>>>> The Enterprise PostgreSQL Company >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> *Akshay Joshi* >>>>>>>>>>> >>>>>>>>>>> *Sr. Software Architect * >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> *Akshay Joshi* >>>>>>>>>> >>>>>>>>>> *Sr. Software Architect * >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Dave Page >>>>>>>>> Blog: http://pgsnake.blogspot.com >>>>>>>>> Twitter: @pgsnake >>>>>>>>> >>>>>>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>>>>>> The Enterprise PostgreSQL Company >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> *Akshay Joshi* >>>>>>>> >>>>>>>> *Sr. Software Architect * >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Dave Page >>>>>>> Blog: http://pgsnake.blogspot.com >>>>>>> Twitter: @pgsnake >>>>>>> >>>>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>>>> The Enterprise PostgreSQL Company >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> *Akshay Joshi* >>>>>> >>>>>> *Sr. Software Architect * >>>>>> >>>>>> >>>>>> >>>>>> *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* >>>>>> >>>>> >>>>> >>>>> -- >>>>> Dave Page >>>>> Blog: http://pgsnake.blogspot.com >>>>> Twitter: @pgsnake >>>>> >>>>> EnterpriseDB UK: http://www.enterprisedb.com >>>>> The Enterprise PostgreSQL Company >>>>> >>>> >>> >>> -- >>> Dave Page >>> Blog: http://pgsnake.blogspot.com >>> Twitter: @pgsnake >>> >>> EnterpriseDB UK: http://www.enterprisedb.com >>> The Enterprise PostgreSQL Company >>> >> > > -- > *Akshay Joshi* > > *Sr. Software Architect * > > > > *Phone: +91 20-3058-9517Mobile: +91 976-788-8246* > -- Dave Page VP, Chief Architect, Tools & Installers EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company Blog: http://pgsnake.blogspot.com Twitter: @pgsnake --00000000000023da64057e778b5b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Tue, Jan 1, 2019 at 9:48 AM Akshay Joshi <akshay.joshi@enterprisedb.com>= ; wrote:
Hi Dave/Hackers

On Mon, Dec 24, 2018 at 7:47 AM Akshay Joshi <akshay= .joshi@enterprisedb.co= m> wrote:


On Fri, 21 Dec 2018, 19:45 Dave Page <dpage@pgadmin.org wrote:


On Fri, Dec 21, 2018 at= 2:08 PM Akshay Joshi <akshay.joshi@enterprisedb.com> = wrote:


On Fri, = 21 Dec 2018, 18:52 Dave Page <dpage@pgadmin.org wrote:
Hi

=
Looks good - I just found one issue; please go ahead and commit = (with a release notes update) when fixed.

- If I s= et the NULL replacement value to an empty string, it defaults back to NULL.= It's therefore not possible to replace null values with an empty value= .

=C2=A0 =C2=A0 If you remember this is the default behaviour of th= e Preferences dialog. It sets the default value again if you set the blank = value. Fahar has raised the same issue before and we have rejected that. If= you think we can create the new RM for that behaviour and will commit the = current patch.

Well, we rejecte= d it for a specific case. In this specific case, it makes sense to be able = to enter a blank value.

Maybe we just need an &quo= t;allow blank" flag on the preference object, that does nothing except= allow you to remove the default (or any other) value without it being repl= aced again? Obviously the default still needs to work until a value is writ= ten to the config DB.=C2=A0

=C2=A0 =C2=A0 Ok. If i understand = correctly this new parameter works for all the preference parameter if set = to true. By default it's value is False and if user wants to enter blan= k value they will ser the flag.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 I think we should not add new preferences flag= "allow blank". Meanwhile I have added new parameter "allow_= blank" to the register function for preferences, so at the time of reg= istering the preference we can set the value of "allow_blank" par= ameter, if blank value is acceptable. I have committed my patch with this c= hanges.=C2=A0

=C2=A0 =C2=A0 =C2=A0 =C2=A0If you th= ink we need that flag as a Preferences object then I'll create a new RM= for it.=C2=A0 =C2=A0=C2=A0

It sounds like you've committed what I just described in my previous= message :-)
=C2=A0
=C2=A0

Thanks!

On Fri, Dec 21, 2018 at 12:57 PM Akshay Joshi <akshay.joshi@enterprisedb.com> wrote:
Hi Dav= e

I have modified the condition, it won't thro= ugh any exception. Attached is the updated patch, please review it.

On Fri, Dec 21, 20= 18 at 4:22 AM Dave Page <dpage@pgadmin.org> wrote:
<= /div>
Sor= ry! Here is is.

On Fri= , Dec 21, 2018 at 12:12 PM Akshay Joshi <akshay.jo= shi@enterprisedb.com> wrote:
Hi Dave

=
Can you please attached the updated patch with your changes. I'll = try to fix the exception.

On Fri, Dec 21, 2018 at 3:57 AM Dave Page <dpage= @pgadmin.org> wrote:
Hi

Here's an updated patch as I've tweaked = some of the wording. The screenshot probably isn't the right resolution= , but as we're replacing them anyway it doesn't seem overly importa= nt. Feel free to fix if you like :-)

With quoting = set to either All or Strings, everything looks good. With it set to None, I= still get an exception (below). The query I'm using is this:

SELECT NULL::text, 1234::int, 'Foo bar'::text, E= 9;Foo\nBar'::text

Field separator: ,
=
Quote character: "
Replace null's with: NULL
<= div>
Steps:

1) Run pgAdmin in Deskto= p mode. I'm running from within PyuCharms, using the venv detailed belo= w.
2) Open the Query Tool on a PostgreSQL 9.6.10 database, runnin= g on MacOS 10.14.1
3) Run the above query, wit quoting set to All= and check the result in the grid.
4) Download the CSV file and c= heck.
5) Open Preferences and set quoting to Strings.
6= ) Download the CSV file and check.
7) Open Preferences and set qu= oting to None.
8) Download the CSV file *exception occurs*.
=


System info:

(pgadmin4) dpage@hal= :~/git/pgadmin4$ python --version

Python 3.6.7

(pgadmin4) dpage@hal= :~/git/pgadmin4$ pip freeze

alabaster=3D=3D0.7.11

alembic=3D=3D1.0.0

asn1crypto=3D=3D0.24.0

Babel=3D=3D2.6.0

bcrypt=3D=3D3.1.4

blinker=3D=3D1.4

certifi=3D=3D2018.8.24

cffi=3D=3D1.11.5

chardet=3D=3D3.0.4

chromedriver-installer=3D=3D0.0.6=

click=3D=3D6.7

cryptography=3D=3D2.3

docutils=3D=3D0.14

extras=3D=3D1.0.0

fixtures=3D=3D3.0.0

Flask=3D=3D0.12.4

Flask-BabelEx=3D=3D0.9.3

Flask-Gravatar=3D=3D0.5.0<= /p>

Flask-HTMLmin=3D=3D1.3.2

Flask-Login=3D=3D0.3.2

Flask-Mail=3D=3D0.9.1

Flask-Migrate=3D=3D2.1.1

Flask-Paranoid=3D=3D0.2.0<= /p>

Flask-Principal=3D=3D0.4.0=

Flask-Security=3D=3D3.0.0<= /p>

Flask-SQLAlchemy=3D=3D2.3.2

Flask-WTF=3D=3D0.14.2

html5lib=3D=3D1.0.1

htmlmin=3D=3D0.1.12

idna=3D=3D2.7

imagesize=3D=3D1.1.0

itsdangerous=3D=3D0.24

Jinja2=3D=3D2.10

linecache2=3D=3D1.0.0

Mako=3D=3D1.0.7

MarkupSafe=3D=3D1.0

packaging=3D=3D18.0

paramiko=3D=3D2.4.1

passlib=3D=3D1.7.1

pbr=3D=3D3.1.1

psutil=3D=3D5.4.8

psycopg2=3D=3D2.7.5

pyasn1=3D=3D0.4.4

pycodestyle=3D=3D2.3.1

pycparser=3D=3D2.18

pycrypto=3D=3D2.6.1

Pygments=3D=3D2.2.0

PyNaCl=3D=3D1.2.1

pyparsing=3D=3D2.2.2

pyperclip=3D=3D1.6.4

pyrsistent=3D=3D0.14.2

python-dateutil=3D=3D2.7.3=

python-editor=3D=3D1.0.3

python-mimeparse=3D=3D1.6.0

pytz=3D=3D2018.3

requests=3D=3D2.19.1

selenium=3D=3D3.14.1

simplejson=3D=3D3.13.2

six=3D=3D1.11.0

snowballstemmer=3D=3D1.2.1=

speaklater=3D=3D1.3

Sphinx=3D=3D1.8.2

sphinxcontrib-websupport=3D=3D1.1= .0

SQLAlchemy=3D=3D1.2.10

sqlparse=3D=3D0.2.4

sshtunnel=3D=3D0.1.4

testscenarios=3D=3D0.5.0

testtools=3D=3D2.3.0

traceback2=3D=3D1.4.0

unittest2=3D=3D1.1.0

urllib3=3D=3D1.23

webencodings=3D=3D0.5.1

Werkzeug=3D=3D0.14.1

WTForms=3D=3D2.1

=

Exception:

20= 18-12-21 11:47:28,995: SQL pgad= min: Execute (with server curso= r) for server #2 - CONN:8760231 (Query-id: 8649354):
SELECT NULL:= :text, 1234::int, 'Foo bar'::text, E'Foo\nBar'::text
<= div>2018-12-21 11:47:29,001: INFO werkzeug: 127.0.0.1 - - [21/= Dec/2018 11:47:29] "GET /sqleditor/query_tool/download/2133388?query= =3DSELECT%20NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%3A%3Atex= t%2C%20E%27Foo%5CnBar%27%3A%3Atext&filename=3Ddata-1545392848979.csv HT= TP/1.1" 500 -
2018-12-21 11:47:29,003: ERROR werkzeug:= Error on request:
Traceback (most recent call last):
=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/si= te-packages/werkzeug/serving.py", line 270, in run_wsgi
=C2= =A0 =C2=A0 execute(self.server.app)
=C2=A0 File "/Users/dpag= e/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py&quo= t;, line 260, in execute
=C2=A0 =C2=A0 for data in application_it= er:
=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/pyth= on3.6/site-packages/werkzeug/wsgi.py", line 870, in __next__
=C2=A0 =C2=A0 return self._next()
=C2=A0 File "/Users/dpage= /.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wrappers.py&quo= t;, line 82, in _iter_encoded
=C2=A0 =C2=A0 for item in iterable:=
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/dr= iver/psycopg2/connection.py", line 848, in gen
=C2=A0 =C2=A0= csv_writer.writerows(results)
=C2=A0 File "/Users/dpage/git= /pgadmin4/web/pgadmin/utils/csv.py", line 761, in writerows
= =C2=A0 =C2=A0 return self.writer.writerows(map(self._dict_to_list, rowdicts= ))
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/= csv.py", line 268, in writerows
=C2=A0 =C2=A0 self.writerow(= row)
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/util= s/csv.py", line 261, in writerow
=C2=A0 =C2=A0 row =3D [self= .strategy.prepare(field, only=3Donly) for field in row]
=C2=A0 Fi= le "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line 261= , in <listcomp>
=C2=A0 =C2=A0 row =3D [self.strategy.prepar= e(field, only=3Donly) for field in row]
=C2=A0 File "/Users/= dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line 142, in prepare
=C2=A0 =C2=A0 raise Error('No escapechar is set')
= _csv.Error: No escapechar is set

=
On Thu, Dec 20, 2018 at 1:05 PM Akshay Joshi <akshay.joshi@enterprisedb.com> wrote:
Hi=C2=A0Dave

On Thu= , Dec 20, 2018 at 5:12 PM Akshay Joshi <akshay.jos= hi@enterprisedb.com> wrote:


On Thu, Dec 20, 2018 at 4:48 PM Dave Pa= ge <dpage@pgadmin.org> wrote:
Hi

On Thu, Dec 20, 2018 at 10:09 AM Akshay Joshi= <akshay.joshi@enterprisedb.com> wrote:
=
Hi Dave

On Thu, Dec 20, 2018 at 3:08 PM Dave Page <dpage@pgadmin.org<= /a>> wrote:
<= div dir=3D"ltr">
Hi

When testing with qu= oting set to None, quote =3D " and delimiter =3D , I get the following= exception when I try to download:

2018-12-20= 09:34:02,547: SQL pgadmin: Execute (with server cursor) for s= erver #2 - CONN:354106 (Query-id: 4121147):
SELECT NULL::text, 12= 34::int, 'Foo bar'::text, E'Foo\nBar'::text
2018-= 12-20 09:34:02,570: INFO werkze= ug: 127.0.0.1 - - [20/Dec/2018 = 09:34:02] "GET /sqleditor/query_tool/download/5610522?query=3DSELECT%2= 0NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%3A%3Atext%2C%20E%27= Foo%5CnBar%27%3A%3Atext&filename=3Ddata-1545298442530.csv HTTP/1.1"= ; 500 -
2018-12-20 09:34:02,572: ERROR werkzeug: Err= or on request:
Traceback (most recent call last):
=C2= =A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packag= es/werkzeug/serving.py", line 270, in run_wsgi
=C2=A0 =C2=A0= execute(self.server.app)
=C2=A0 File "/Users/dpage/.virtual= envs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", line 2= 60, in execute
=C2=A0 =C2=A0 for data in application_iter:
<= div>=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site= -packages/werkzeug/wsgi.py", line 870, in __next__
=C2=A0 = =C2=A0 return self._next()
=C2=A0 File "/Users/dpage/.virtua= lenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wrappers.py", line= 82, in _iter_encoded
=C2=A0 =C2=A0 for item in iterable:
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/driver/psy= copg2/connection.py", line 820, in gen
=C2=A0 =C2=A0 csv_wri= ter.writerows(results)
=C2=A0 File "/Users/dpage/git/pgadmin= 4/web/pgadmin/utils/csv.py", line 748, in writerows
=C2=A0 = =C2=A0 return self.writer.writerows(map(self._dict_to_list, rowdicts))
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py&= quot;, line 256, in writerows
=C2=A0 =C2=A0 self.writerow(row)
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.p= y", line 249, in writerow
=C2=A0 =C2=A0 row =3D [self.strate= gy.prepare(field, only=3Donly) for field in row]
=C2=A0 File &quo= t;/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line 249, in &l= t;listcomp>
=C2=A0 =C2=A0 row =3D [self.strategy.prepare(field= , only=3Donly) for field in row]
=C2=A0 File "/Users/dpage/g= it/pgadmin4/web/pgadmin/utils/csv.py", line 136, in prepare
= =C2=A0 =C2=A0 raise Error('No escapechar is set')
_csv.Er= ror: No escapechar is set


=

=C2=A0 =C2=A0 =C2=A0 Attached is the modified patch as = per your suggestion.=C2=A0
= =C2=A0

On Tue, Dec 18, 2018 at 11:13 AM A= kshay Joshi <akshay.joshi@enterprisedb.com>= wrote:
Hi=C2=A0Dave

Attached is the modified patch to = fix review comments.


<= br>
Hi

On Tue, Dec 18, 2018 at 3:45 AM Ak= shay Joshi <akshay.joshi@enterprisedb.com> = wrote:
Hi Hackers,

Attached is the pa= tch to fix RM #3780=C2=A0pgAdmin4 lacks ability to specify NULL values in <= span id=3D"gmail-m_-438485566356105819m_-2971125863169574135m_-782094290580= 8905750gmail-m_6761893864494179304m_-7022379468613173924gmail-m_-4221668608= 989975125m_-4795771608800120050gmail-m_2246641537666896898gmail-m_655141376= 7568803173gmail-m_-6796796050964945676gmail-m_-5991412030039016026gmail-m_-= 2894014154183785825gmail-m_-455675873228126996gmail-m_-3511925126658346770g= mail-m_361423959471310265gmail-m_-1300974772564471919gmail-m_50441649117995= 42113gmail-m_8445853776182989198gmail-m_-7063081395761107541gmail-m_-364023= 7263547570362:1ww.4">CSV export.

Please rev= iew it.

A few points;

- You've included code from backports.csv, but pe= r the licence you need to include a description of the changes made.
<= /div>

=C2=A0 =C2=A0 =C2=A0 Sure. In t= hat case I'll copy the complete file and will do my changes which is of= two lines only. With my patch I have remove all the unwanted code from bac= kport.csv.=C2=A0 =C2=A0 =C2=A0=C2=A0

- Shouldn't backports.csv be removed from requirements.txt, or is= it used elsewhere?

=C2= =A0 =C2=A0 =C2=A0Yes. Will do that.=C2=A0

=
- If the previous point is true, then I'm fairly sure there = is code in one or more of the many package build scripts that adds an __ini= t__.py file to backports.csv in the venv that's created.

=C2=A0 =C2=A0 I'll remove that code= as well.=C2=A0=C2=A0
=C2=A0
--
Dave Page
Blog: http://pgsnake.blogspot.c= om
Twitter: @pgsnake

EnterpriseDB UK: http://www= .enterprisedb.com
The Enterprise PostgreSQL Company


--
Aksh= ay Joshi
Sr. Software Architect


Phone: +91 20-3058-9517
Mobile: +91= 976-788-8246


--
Akshay Joshi<= /div>
Sr. Softwar= e Architect

Phone: +91 20-3058-9517
Mobile: +91 976-788-8246


--
Dave P= age
Blog: http://pgsnake.blogspot.com
Twitter: @pgsn= ake

EnterpriseDB UK: http://www.enterprisedb.comThe Enterprise PostgreSQL Company


--
Akshay Josh= i
Sr. Software Architect


= Phone: +91 20-3058-9517
Mobile: +91 976-78= 8-8246


--


--
Akshay Joshi
= Sr. Software Architect
=


Phone: +91 20-3058-9517<= br>Mobile: +91 976-788-8246
=


--
<= div>Akshay Joshi
Sr. Software Architect


Phone: +91 20-3058-9517
Mobile: +91 976-788-8246=


--
Dave Page
Blog: http://pgsnake.blogspot.com
T= witter: @pgsnake

EnterpriseDB UK: http://www.enterprise= db.com
The Enterprise PostgreSQL Company


--
Akshay = Joshi
Sr. Software Architect


Phone: +91 20-3058-9517
Mobile: +91 97= 6-788-8246


--
Dave Page
Blog: http://pgsnake.bl= ogspot.com
Twitter: @pgsnake

EnterpriseDB UK: ht= tp://www.enterprisedb.com
The Enterprise PostgreSQL Company


--
Akshay Joshi
Sr. Software Architect


Phone: +91 20-3058-9517=
Mobile: +91 976-788-8246


--
Dave Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake

Enterpris= eDB UK: http://www.enterprisedb.com
The Enterprise Post= greSQL Company


--
Dav= e Page
Blog: http://pgsnake.blogspot.com
Twitter: @pgsnake
<= br>EnterpriseDB UK: http://www.enterprisedb.com
The Enterprise Pos= tgreSQL Company


--
Akshay Joshi
= Sr. Software Architect
=


Phone: +91 20-3058-9517<= br>Mobile: +91 976-788-8246
=

--
Dave Page
VP, Chief Architect, Tools & In= stallers
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Compa= ny

Blog: h= ttp://pgsnake.blogspot.com
Twitter: @pgsnake
--00000000000023da64057e778b5b--