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 1geeEr-0002BL-0I for pgadmin-hackers@arkaria.postgresql.org; Wed, 02 Jan 2019 10:59:05 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1geeEp-0006QS-12 for pgadmin-hackers@arkaria.postgresql.org; Wed, 02 Jan 2019 10:59:03 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1geeEo-0006PZ-5F for pgadmin-hackers@lists.postgresql.org; Wed, 02 Jan 2019 10:59:02 +0000 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1geeEi-00008K-Sy for pgadmin-hackers@postgresql.org; Wed, 02 Jan 2019 10:59:00 +0000 Received: by mail-wr1-x443.google.com with SMTP id r10so30050945wrs.10 for ; Wed, 02 Jan 2019 02:58:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pgadmin-org.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=7Aq4AWMxqy46876EMPSBbx1rigKZFJIx+Q69Dy8zU+M=; b=Jlu9Fe47RRRX3f2BW+H0CIgNCVuIcIKMg1gPtqYLUOlh6zh/RZkHg4mdAjZUrZK6Rh PIl+73qA0PfywwfIHSMH/LVKfjmhT1UysKengbH9VH4MhI9h9tgC1Ct6Gn7OURMcF4GN DFUtvzZv4OWGA3nL807m9vMac9rnXZmQ93Em4VOIVetzg7sNZvaiumdR+jFkBpWkOcJ3 c2xUr5Iusr75zU5MgP2EqjPWCufXIhDsa+ER37JeJA53/W+zspnzyvnfkKTtG5pZQEaO 4D1VSdaI1sNOrngoiobXOaSC1cN+LO9xTWjHVkycXVEL2SgkWpYJ/DFwm/LqTlRN+HgL J1vw== 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=7Aq4AWMxqy46876EMPSBbx1rigKZFJIx+Q69Dy8zU+M=; b=XUXtxAe1E9+FoaXUKnCKYOft3iIBlwqgpJcWBBtIvUrsiTXzX965+j3x8dMrsUNl0V 49AtyunbLTfritd3G0bzRFt5KxFxnPB9MyEdE84EqupIBJxBNq4gWCC0v6xWNrLKJhK2 9/RFZCDkjxJi5P8+scYb1VC0KdUkrAB0azYKRoCjvFyEh/sfky63S+EBqxS72f2m5ZsM oI1a3zvYhdp8SPjc8FJGudbopXv/uW1JhZPdeJpbCtS4x8egF/ZExGojYmalwg/o1wHv KLqTK9b7ohQXIIBKOzfuYDUoUX2ZJ8BgURQZVFra618oH/XOxyd1qgIZeO0tjAoxxvAo wNcg== X-Gm-Message-State: AJcUukf0l+N5jQkbK9TmA8LhuL7NDK+YtrP+8ylpaXL+c6Jbktnzt3qU /5xvXu69baMNjn6BDQaKbwlSou15Jj1yMnRmUcAhCg== X-Google-Smtp-Source: ALg8bN5rdY7YoMb4m0c2Y27NqU7J8ZQoYTjMdvh4m49p31ZyFHyjJZf+MpIJzp8qT3Iz92QBmi3xUxL+IidT3NBJW7M= X-Received: by 2002:adf:8264:: with SMTP id 91mr36399376wrb.312.1546426734604; Wed, 02 Jan 2019 02:58:54 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Dave Page Date: Wed, 2 Jan 2019 10:58:43 +0000 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="000000000000300d9a057e778872" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --000000000000300d9a057e778872 Content-Type: text/plain; charset="UTF-8" On Mon, Dec 24, 2018 at 2:17 AM Akshay Joshi 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. > No - it would be an internal flag that the user won't see. If set to false, then attempts to change a field to would actually set it to it's default (e.g. for binary paths, it would set it back to the default from config.py). If set to true, then attempts to change a field to would be accepted. The default value would only be used until such time as its overridden by the user. > >> >>> >>>> 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 >>>>>>>>>>>>>>> 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 >> > -- Dave Page Blog: http://pgsnake.blogspot.com Twitter: @pgsnake EnterpriseDB UK: http://www.enterprisedb.com The Enterprise PostgreSQL Company --000000000000300d9a057e778872 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


=
On Mon, Dec 24, 2018 at 2:17 AM Akshay Joshi <akshay.joshi@enterprisedb.com= > wrote:


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

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


On Fri, 21 D= ec 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 set the= NULL replacement value to an empty string, it defaults back to NULL. It= 9;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 the Prefe= rences 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 th= ink we can create the new RM for that behaviour and will commit the current= patch.

Well, we rejected it fo= r a specific case. In this specific case, it makes sense to be able to ente= r 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 ag= ain? Obviously the default still needs to work until a value is written to = the config DB.=C2=A0

=C2=A0 =C2=A0 Ok. If i understand correct= ly 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.

No - i= t would be an internal flag that the user won't see.=C2=A0
If set to false, then attempts to change a field to <blank&= gt; would actually set it to it's default (e.g. for binary paths, it wo= uld set it back to the default from config.py).

If= set to true, then attempts to change a field to <blank> would be acc= epted. The default value would only be used until such time as its overridd= en by the user.
=C2=A0
=C2=A0
=
Thanks!

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

<= /div>
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 Dav= e Page <dpage@pgadmin.org> 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 plea= se attached the updated patch with your changes. I'll try to fix the ex= ception.

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

<= /div>
Here's an updated patch as I've tweaked some of the wordi= ng. The screenshot probably isn't the right resolution, but as we'r= e 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 exc= eption (below). The query I'm using is this:

S= ELECT NULL::text, 1234::int, 'Foo bar'::text, E'Foo\nBar'::= text

Field separator: ,
Quote charac= ter: "
Replace null's with: NULL

Steps:

1) Run pgAdmin in Desktop mode. I'm r= unning from within PyuCharms, using the venv detailed below.
2) O= pen 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 re= sult in the grid.
4) Download the CSV file and check.
5= ) Open Preferences and set quoting to Strings.
6) Download the CS= V 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 --versi= on

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<= /span>

Babel=3D=3D2.6.0=

bcrypt=3D=3D3.1.4

blinker=3D=3D1.4=

certifi=3D=3D2018.8.24<= /span>

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

Flask-HTMLmin=3D=3D1.3.= 2

Flask-Login=3D=3D0.3.2<= /span>

Flask-Mail=3D=3D0.9.1

Flask-Migrate=3D=3D2.1.= 1

Flask-Paranoid=3D=3D0.2= .0

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

Flask-Security=3D=3D3.0= .0

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<= /span>

Jinja2=3D=3D2.10=

linecache2=3D=3D1.0.0

Mako=3D=3D1.0.7<= /p>

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<= /span>

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<= /span>

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<= /span>

six=3D=3D1.11.0<= /p>

snowballstemmer=3D=3D1.= 2.1

speaklater=3D=3D1.3

Sphinx=3D=3D1.8.2

sphinxcontrib-websuppor= t=3D=3D1.1.0

SQLAlchemy=3D=3D1.2.10<= /span>

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:

2018-12-21 11:47:28,995: SQL <= /span>pgadmin: Execute (with se= rver cursor) for server #2 - CONN:8760231 (Query-id: 8649354):
SE= LECT NULL::text, 1234::int, 'Foo bar'::text, E'Foo\nBar'::t= ext
2018-12-21 11:47:29,001: INFO werkzeug: 127.0.0.= 1 - - [21/Dec/2018 11:47:29] "GET /sqleditor/query_tool/download/21333= 88?query=3DSELECT%20NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%= 3A%3Atext%2C%20E%27Foo%5CnBar%27%3A%3Atext&filename=3Ddata-154539284897= 9.csv HTTP/1.1" 500 -
2018-12-21 11:47:29,003: ERROR werkzeug: Error on request:
Traceback (most recent call las= t):
=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/pyth= on3.6/site-packages/werkzeug/serving.py", line 270, in run_wsgi
<= div>=C2=A0 =C2=A0 execute(self.server.app)
=C2=A0 File "/Use= rs/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving= .py", line 260, in execute
=C2=A0 =C2=A0 for data in applica= tion_iter:
=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/l= ib/python3.6/site-packages/werkzeug/wsgi.py", line 870, in __next__
=C2=A0 =C2=A0 return self._next()
=C2=A0 File "/User= s/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/wrappers= .py", line 82, in _iter_encoded
=C2=A0 =C2=A0 for item in it= erable:
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/u= tils/driver/psycopg2/connection.py", line 848, in gen
=C2=A0= =C2=A0 csv_writer.writerows(results)
=C2=A0 File "/Users/dp= age/git/pgadmin4/web/pgadmin/utils/csv.py", line 761, in writerows
=C2=A0 =C2=A0 return self.writer.writerows(map(self._dict_to_list, r= owdicts))
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin= /utils/csv.py", line 268, in writerows
=C2=A0 =C2=A0 self.wr= iterow(row)
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadm= in/utils/csv.py", line 261, in writerow
=C2=A0 =C2=A0 row = =3D [self.strategy.prepare(field, only=3Donly) for field in row]
= =C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py",= line 261, in <listcomp>
=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 142, in pr= epare
=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 <aks= hay.joshi@enterprisedb.com> wrote:


<= div class=3D"gmail_quote">
On Thu, Dec 20, 2018 at 4:48 PM = Dave Page <dpage@pgadmin.org> wrote:
Hi

On Thu, Dec 20, 2018 at 10:09 AM Aksha= y Joshi <akshay.joshi@enterprisedb.com> wro= te:
Hi Dave

On Thu, Dec 20, 2018 at 3:08 PM Dave Page <dpage@pgad= min.org> wrote:
Hi

When testing= with quoting set to None, quote =3D " and delimiter =3D , I get the f= ollowing exception when I try to download:

20= 18-12-20 09:34:02,547: SQL pgad= min: Execute (with server curso= r) 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/D= ec/2018 09:34:02] "GET /sqleditor/query_tool/download/5610522?query=3D= SELECT%20NULL%3A%3Atext%2C%201234%3A%3Aint%2C%20%27Foo%20bar%27%3A%3Atext%2= C%20E%27Foo%5CnBar%27%3A%3Atext&filename=3Ddata-1545298442530.csv HTTP/= 1.1" 500 -
2018-12-20 09:34:02,572: ERROR werkzeug: Error on request:
Traceback (most recent call last):
=C2=A0 File "/Users/dpage/.virtualenvs/pgadmin4/lib/python3.6/site-= packages/werkzeug/serving.py", line 270, in run_wsgi
=C2=A0 = =C2=A0 execute(self.server.app)
=C2=A0 File "/Users/dpage/.v= irtualenvs/pgadmin4/lib/python3.6/site-packages/werkzeug/serving.py", = line 260, 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/.vi= rtualenvs/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= /psycopg2/connection.py", line 820, in gen
=C2=A0 =C2=A0 csv= _writer.writerows(results)
=C2=A0 File "/Users/dpage/git/pga= dmin4/web/pgadmin/utils/csv.py", line 748, in writerows
=C2= =A0 =C2=A0 return self.writer.writerows(map(self._dict_to_list, rowdicts))<= /div>
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv= .py", line 256, in writerows
=C2=A0 =C2=A0 self.writerow(row= )
=C2=A0 File "/Users/dpage/git/pgadmin4/web/pgadmin/utils/c= sv.py", line 249, in writerow
=C2=A0 =C2=A0 row =3D [self.st= rategy.prepare(field, only=3Donly) for field in row]
=C2=A0 File = "/Users/dpage/git/pgadmin4/web/pgadmin/utils/csv.py", line 249, i= n <listcomp>
=C2=A0 =C2=A0 row =3D [self.strategy.prepare(f= ield, only=3Donly) for field in row]
=C2=A0 File "/Users/dpa= ge/git/pgadmin4/web/pgadmin/utils/csv.py", line 136, in prepare
<= div>=C2=A0 =C2=A0 raise Error('No escapechar is set')
_cs= v.Error: No escapechar is set

=
=C2=A0 =C2=A0 Not able to reproduce the above issue. I have test= ed 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.c= sv=C2=A0

"text","int4","text-2&q= uot;,"text-3"

"","1234","Foo bar"= ;,"Foo

Bar"


Isn't the point for it to be NULL?=

=C2=A0 =C2= =A0 while quoting is set to ALL, all the data types has been quoted, so I t= hought 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.
<= div>
So how would you distinguish NULL from an empty string? = Isn't that exactly what the bug is about?

I st= ill think we need a "Replace NULLs with" config option, and regar= dless of quoting settings we always replace NULL values with whatever that = is set to=C2=A0 - for which the user could then choose options like:
<= div>
NULL
"NULL"
""
''
<empty string>

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.


=C2=A0 =C2=A0OK, = Will work on it and send the modified patch again.=C2=A0
<= /blockquote>

=C2=A0 =C2=A0 =C2=A0 Attached is the modifi= ed patch as per your suggestion.=C2=A0
=C2=A0
<= div dir=3D"ltr">

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

Attached is the modifi= ed 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:<= br>
Hi

On Tue, Dec 18, 2018= at 3:45 AM Akshay Joshi <akshay.joshi@enterprised= b.com> wrote:
Hi Hackers,

Attac= hed is the patch to fix RM #3780=C2=A0pgAdmin4 lacks ability to specify NUL= L values in CSV export.

Please review it.

A few points;

- You've included code from bac= kports.csv, but per the licence you need to include a description of the ch= anges made.

=C2=A0 =C2=A0= =C2=A0 Sure. In that case I'll copy the complete file and will do my c= hanges which is of two lines only. With my patch I have remove all the unwa= nted code from backport.csv.=C2=A0 =C2=A0 =C2=A0=C2=A0

- Shouldn't backports.csv be removed from requi= rements.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 fa= irly sure there is code in one or more of the many package build scripts th= at adds an __init__.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.com
Twitter: @pgsnake

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


--
=
Akshay Joshi
Sr. Software Architect

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


--
Akshay Joshi
Sr. So= ftware Architect
<= b>

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


--


--
Akshay= Joshi
Sr. Software Architect


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


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

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


--
Akshay Joshi
Sr. Software Architect
<= /font>

=

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


--
Akshay Joshi=
Sr. Software Architect


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


--


--
Aksh= ay Joshi
Sr. Software Architect


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


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

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


--
Akshay Joshi
Sr. Software Architect
<= /font>

=

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

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

Enterp= riseDB UK: http://www.enterprisedb.com
The Enterprise P= ostgreSQL Company


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

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


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

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