<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jady Nekena</title>
    <description>The latest articles on DEV Community by Jady Nekena (@jadyrama).</description>
    <link>https://dev.to/jadyrama</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F657733%2F21460c00-921f-448a-87d3-91c81a640538.jpeg</url>
      <title>DEV Community: Jady Nekena</title>
      <link>https://dev.to/jadyrama</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jadyrama"/>
    <language>en</language>
    <item>
      <title>I discovered the largest files in my Windows C disk</title>
      <dc:creator>Jady Nekena</dc:creator>
      <pubDate>Wed, 17 Aug 2022 15:15:31 +0000</pubDate>
      <link>https://dev.to/jadyrama/i-discovered-the-largest-files-in-my-windows-c-disk-1fd</link>
      <guid>https://dev.to/jadyrama/i-discovered-the-largest-files-in-my-windows-c-disk-1fd</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Have you ever wondered what are the largest files in your local disk ? Well, I also did. But at the same time, I had two constraints on mind :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I &lt;strong&gt;didn't want to use any third party tool&lt;/strong&gt; to process the disk scan.&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;was absolutely not going to scan it manually&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article will show you step by step how I did it. But before we're diving in, let me show you the final &lt;strong&gt;Tableau&lt;/strong&gt; data vizualisations, which are quite satisfying !&lt;/p&gt;

&lt;h2&gt;
  
  
  Dataviz results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  First dataviz
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/summary.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Fsummary.png" alt="Extension total sizes, grouped by usefulness"&gt;&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Extension total sizes, grouped by usefulness&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Insights&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are &lt;strong&gt;a lot&lt;/strong&gt; of files without any extension (light blue on the left-hand side).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;ucas&lt;/strong&gt; files from Unreal Engine archives actually make sense, as I do play &lt;strong&gt;Fortnite&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;vsix&lt;/strong&gt; files are some visual code extensions. I still wonder how they came into my computer, &lt;strong&gt;I only use Sublime text as main editor&lt;/strong&gt;...&lt;/li&gt;
&lt;li&gt;I didn't realize how big my &lt;strong&gt;png photos&lt;/strong&gt; were until this chart showed it up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Second dataviz
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/most-used-extensions.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Fmost-used-extensions.png" alt="Extensions with their total sizes and number of files, grouped by usefulness"&gt;&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Extensions with their total sizes and number of files, grouped by usefulness&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Insights&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On average, &lt;strong&gt;OS files&lt;/strong&gt; are &lt;strong&gt;bigger&lt;/strong&gt; than non-OS ones.&lt;/li&gt;
&lt;li&gt;There are &lt;strong&gt;more than 150k files without any extension&lt;/strong&gt; (I assumed they are for the OS but who knows?).&lt;/li&gt;
&lt;li&gt;There are &lt;strong&gt;only 171 ucas files&lt;/strong&gt;, which means that &lt;strong&gt;1 ucas file is larger than the average&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;I honestly &lt;strong&gt;should remove the useless 2Gb used by vsix&lt;/strong&gt; files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Third dataviz
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/files-depth.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Ffiles-depth.png" alt="Number of files per folder depth"&gt;&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Number of files per folder depth&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Insights&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are &lt;strong&gt;24 levels of folders&lt;/strong&gt;, where the first one is the disk itself &lt;code&gt;C:/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most used directories&lt;/strong&gt; are generally &lt;strong&gt;between 4th and 12th depth&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6th level don't contain a lot of files&lt;/strong&gt; : there must be only subdirectories in this folder depth.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fourth dataviz
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/folders-depths.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Ffolders-depths.png" alt="Folders depths grouped by usefulness"&gt;&lt;/a&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Folders depths grouped by usefulness&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;1 dot = 1 file&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;1 color = 1 folder&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;Y axis = folder depth starting with 1, from top to bottom&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Insights&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The far we go down (to &lt;strong&gt;greater directories depth&lt;/strong&gt;), the &lt;strong&gt;less are the amount of files&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Empty spaces that are created in non-OS files stand for &lt;strong&gt;exclusive OS folders&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Among OS files&lt;/strong&gt;, those large lined-up areas stand for &lt;strong&gt;Microsoft Services&lt;/strong&gt; files :
![os-folder-1][os-folder-1] ![os-folder-2][os-folder-2] &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Among non-OS files&lt;/strong&gt;, the large pink and green lines stands for &lt;code&gt;%AppData%&lt;/code&gt; subfolders, where all &lt;strong&gt;caching&lt;/strong&gt; processes are happening and stored :
![pink-line][pink-line]&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How did I do it
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gathering files details
&lt;/h3&gt;

&lt;p&gt;Before having the above final vizualisation, the first step is obviously to gather datas. I just used the following two lines code from my &lt;strong&gt;cmd terminal&lt;/strong&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd C:/
where "*.*" /r . /t &amp;gt; f:\list-of-c-files.txt 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note that &lt;strong&gt;the output file is stored out of the scanned disk&lt;/strong&gt; so that it doesn't interfer while scanning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Initial output
&lt;/h3&gt;

&lt;p&gt;The output will look like shown below :&lt;br&gt;
&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/first-raw-datas.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Ffirst-raw-datas.png" alt="First raw datas outputed from script"&gt;&lt;/a&gt;&lt;br&gt;
Quite ugly, right ? Let's do some cleaning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data cleaning
&lt;/h3&gt;

&lt;p&gt;This step can be done in any software or programming language that you like. In my case, I directly used &lt;strong&gt;Tableau Software&lt;/strong&gt;.   &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I &lt;strong&gt;import the initial file&lt;/strong&gt; as a text file with a &lt;strong&gt;random non-used character as delimiter&lt;/strong&gt;. From this way, I can customize all new calculated fields from raw datas manually. In my case, I used &lt;code&gt;^&lt;/code&gt; as the seen in this (french version) screenshot from &lt;strong&gt;Tableau Software Desktop&lt;/strong&gt; : &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Fdelimiter.png" alt="delimiter"&gt;
&lt;/li&gt;
&lt;li&gt;I create all the &lt;strong&gt;new calculated fields&lt;/strong&gt; and &lt;strong&gt;hide&lt;/strong&gt; the single raw column &lt;code&gt;src_all&lt;/code&gt; :
&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/calculated-fields.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Fcalculated-fields.png" alt="calculated-fields"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I &lt;strong&gt;preview final output datas&lt;/strong&gt; to make sure everything fits to what I expected :
&lt;a href="https://data-addict.jadynekena.com/assets/img/2022-08-17/final-output.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.jadynekena.com%2Fassets%2Fimg%2F2022-08-17%2Ffinal-output.png" alt="final-output"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's it, &lt;strong&gt;we are ready to dataviz&lt;/strong&gt; !&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to preview your own files...
&lt;/h2&gt;

&lt;p&gt;Just ping me on &lt;a href="https://twitter.com/jadyrama" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and I will be glad to give you the &lt;strong&gt;Tableau template&lt;/strong&gt; to get started quickly !&lt;/p&gt;

&lt;p&gt;Feel free to &lt;strong&gt;tell me what are your thoughts&lt;/strong&gt; on this side-project of mine on the comments section below.&lt;/p&gt;

</description>
      <category>tableau</category>
      <category>dataviz</category>
      <category>vizualisation</category>
      <category>windows</category>
    </item>
    <item>
      <title>Retrieve datas from postgreSQL to Google Sheets with Heroku for free</title>
      <dc:creator>Jady Nekena</dc:creator>
      <pubDate>Sat, 26 Jun 2021 05:29:20 +0000</pubDate>
      <link>https://dev.to/jadyrama/retrieve-datas-from-postgresql-to-google-sheets-with-heroku-for-free-55a5</link>
      <guid>https://dev.to/jadyrama/retrieve-datas-from-postgresql-to-google-sheets-with-heroku-for-free-55a5</guid>
      <description>&lt;h1&gt;
  
  
  Motivation
&lt;/h1&gt;

&lt;p&gt;Connecting postgreSQL to Google Sheets might be tricky, as there is no explicit solution to do so, unless you use third party tools such as Zapier, Kloud.io or Blend.co. Moreover, some of those solutions are not forever free.&lt;br&gt;&lt;br&gt;
As a developer, I’d rather create my own things, and share them with people who might need them for their own projects. Let’s see how it goes.&lt;/p&gt;
&lt;h1&gt;
  
  
  Why doing this?
&lt;/h1&gt;

&lt;p&gt;The main goal is to retrieve datas from a place to another : basically for &lt;strong&gt;better monitoring&lt;/strong&gt;. As you may know, Google Sheets is available from Desktop and mobile, and it’s free to use. You will see some scripts on Google Appscripts that will empower your app easily. You can also connect your sheets to Tableau Public for some magical Data Viz, and refresh datas daily without any effort from you. You can find how to do so here.&lt;/p&gt;
&lt;h1&gt;
  
  
  Some assumptions before we begin
&lt;/h1&gt;

&lt;p&gt;The following code is assuming that you’re using the same dbname-username-password for all the databases that you want to monitor. Of course, if this assumption is not true, you should write down a new way to handle all dbnames-users-passwords, by changing the variables &lt;code&gt;DB_NAME&lt;/code&gt;, &lt;code&gt;DB_USERNAME&lt;/code&gt; and &lt;code&gt;DB_PASSWORD&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Let’s do it in 5 Steps
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1. Create few accounts
&lt;/h2&gt;

&lt;p&gt;You will need to register to the following tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://accounts.google.com" rel="noopener noreferrer"&gt;Google Drive&lt;/a&gt; of course&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/join" rel="noopener noreferrer"&gt;Github&lt;/a&gt; for creating a postgreSQL database on &lt;a href="https://app.supabase.io/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt; and hosting your future python code&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://signup.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt; for your python server, using flask&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you’re done signing up to these 3 platforms, let’s go to step 2.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. (Optional) PostgreSQL database on Supabase in less than 2 minutes
&lt;/h2&gt;

&lt;p&gt;If you already have a postgreSQL database to monitor, discard this step and go to step 3 directly.&lt;/p&gt;
&lt;h3&gt;
  
  
  The database
&lt;/h3&gt;

&lt;p&gt;If you never heard about Supabase, it’s the open source firebase alternative, using postgreSQL. They are offering a free tier pricing for 3 hobby projects, that you may use for the purpose we have here. To get started, just sign up with your Github account, and allow all required credentials.&lt;/p&gt;

&lt;p&gt;Once logged in, click on New Project &amp;gt; Your org’s name.&lt;/p&gt;

&lt;p&gt;Provide the project name, the database password, and the region closest to your current location. In this example, I’m going to use the following details:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt; : &lt;code&gt;my-super-project&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Database password&lt;/strong&gt; : &lt;code&gt;hellothisisapasswordandihopeitsstrongenough2021&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Region&lt;/strong&gt; : &lt;code&gt;West EU (London)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Just let the magic process for 1 minute or 2.&lt;/p&gt;
&lt;h3&gt;
  
  
  The table that will be fetched
&lt;/h3&gt;

&lt;p&gt;Once your database is ready, use the button on the left side bar: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fsupabase-sql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fsupabase-sql.png" alt="supabase-SQL"&gt;&lt;/a&gt; to run the following SQL query. It will create the table you will retrieve datas from later on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE public.conv
(
    id uuid NOT NULL DEFAULT uuid_generate_v4(),
    sender character varying COLLATE pg_catalog."default",
    receiver character varying COLLATE pg_catalog."default",
    content text COLLATE pg_catalog."default",
    datetime timestamp with time zone DEFAULT now(),
    CONSTRAINT conv_pkey PRIMARY KEY (id)
) TABLESPACE pg_default;

COMMENT ON COLUMN public.conv.sender
    IS 'the one who sends the message';

COMMENT ON COLUMN public.conv.receiver
    IS 'the one supposed to receive the message';

COMMENT ON COLUMN public.conv.content
    IS 'the actual message';

COMMENT ON COLUMN public.conv.datetime
    IS 'the date time the sender sends the content to the receiver';

ALTER TABLE ONLY public.conv ADD CONSTRAINT conv_pkey PRIMARY KEY (id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s insert some datas in it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;d5f67084-c0ca-4ae5-8957-348237ba51be    A   B   Hey! It's been a while. How you're doing?   2021-06-26 12:03:22+00
5287170c-b6f6-47fe-ad0c-9f724ef60acb    B   A   Hey.\nThanks for your message. I'm doing fine, thanks!\nWhat's up?  2021-06-26 12:03:31+00
1c927c51-dd2f-4f1c-9ead-609f71b7747e    A   B   Nothing much. Wanna hang out tonight?   2021-06-26 12:04:10+00
f243838c-1596-46d1-86d5-304def0840db    B   A   Sure, I must be free at 7pm. What was the name of the bar we used to hang out in?   2021-06-26 12:04:50+00
a3ce9c80-8333-4fc7-8d27-7c19c31326d4    A   B   Foo. The Foo Bar.   2021-06-26 12:05:45+00
8f990cc9-35e7-4fa8-baac-d87bcf9f213e    B   A   Oh, yeah. How could I forget something that is so obvious. LOL  2021-06-26 12:06:14+00
02c18b5f-098e-479e-bcf5-42946cf34fe1    A   B   See you there btw, is 7:30pm ok for you?    2021-06-26 12:07:02+00
6fb02446-263d-4bf9-bdc1-51ad7f03c40c    B   A   Perfect. See you!   2021-06-26 12:07:23+00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your supabase table must now look like this:&lt;br&gt;&lt;br&gt;
 &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ffinal-datas.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ffinal-datas.PNG" alt="final-supabase-datas"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Create your python server hosted in Github and deployed on Heroku
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The connection string
&lt;/h3&gt;

&lt;p&gt;Your database connection string should look like this: &lt;code&gt;postgres(ql)://user:password@your-host-location.com:portnumber/dbname&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you created a database from Supabase, you can find it in Settings &amp;gt; Database &amp;gt; Connection string. The actual connection string will look like this: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fconnection-string-postgres.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fconnection-string-postgres.png" alt="connection-string-preview"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you have this connection string, let’s code!&lt;/p&gt;
&lt;h3&gt;
  
  
  Fork the github project
&lt;/h3&gt;

&lt;p&gt;Directly from the &lt;a href="https://github.com/jadynekena/python-server-heroku" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  The python server
&lt;/h4&gt;

&lt;p&gt;Our goal here is to create the controller that receives a SQL statement (such as &lt;code&gt;SELECT * FROM NAMETABLE&lt;/code&gt;), and gives back the datas as JSON. It’s actually a REST API controller.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Important cautions&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The following method is &lt;strong&gt;not&lt;/strong&gt; secure. You will write down your postgreSQL database password inside your code, so be sure to host the file in a &lt;strong&gt;private repo&lt;/strong&gt; on github.&lt;/li&gt;
&lt;li&gt;If your datas are sensitive, you should consider implementing some authentication layer before accessing to your Heroku app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now create a local directory, named &lt;code&gt;python-server&lt;/code&gt; for example. From now on, you will need to create &lt;strong&gt;5 files&lt;/strong&gt;. &lt;strong&gt;2 of those 5 files will be auto-generated&lt;/strong&gt; , you will read more about it later, just right here&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;app.py&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The code is &lt;a href="https://raw.githubusercontent.com/jadynekena/python-server-heroku/main/app.py" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;cert.pem and key.pem&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Those 2 files are auto-generated, generally from openssl in terminal, or an easier solution like this &lt;a href="https://8gwifi.org/SelfSignCertificateFunctions.jsp" rel="noopener noreferrer"&gt;website that provides self-signed certificates&lt;/a&gt;. Once you provide the Common Name, you can generate both files and have some kind of texts like this: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fcert-key-generated.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fcert-key-generated.PNG" alt="cert-key-generated"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your root directory (&lt;code&gt;python-server&lt;/code&gt; in our example), copy and paste the :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate in a file named &lt;code&gt;cert.pem&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Private Key in a file named &lt;code&gt;key.pem&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;requirements.txt&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The code is &lt;a href="https://raw.githubusercontent.com/jadynekena/python-server-heroku/main/requirements.txt" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
It’s telling you (and Heroku right before deployment) the useful dependancies for your project.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;Procfile&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The code is &lt;a href="https://raw.githubusercontent.com/jadynekena/python-server-heroku/main/Procfile" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;&lt;br&gt;
It’s starting the server while on Heroku.&lt;/p&gt;



&lt;p&gt;I promise we’re almost done! You can run it locally to verify that everyhing works fine. Run &lt;code&gt;python app.py&lt;/code&gt; then go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://127.0.0.1:5000/&amp;lt;YOUR-DB-HOST&amp;gt;/&amp;lt;YOUR-SELECT-STATEMENT&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my case, I have this JSON: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Freturned-datas-from-localhost-json.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Freturned-datas-from-localhost-json.PNG" alt="results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, push all those files in your forked and &lt;strong&gt;private&lt;/strong&gt; repo on github.&lt;br&gt;&lt;br&gt;
Once you’re done, go to your Heroku account, we’re going to create your app.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. The Heroku project
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Init the project
&lt;/h3&gt;

&lt;p&gt;After logging in, go to &lt;a href="https://dashboard.heroku.com/apps" rel="noopener noreferrer"&gt;your Heroku dashboard&lt;/a&gt; and click on Create new app.&lt;br&gt;&lt;br&gt;
For my example, I will use the same name as from the repo: &lt;code&gt;python-server-heroku&lt;/code&gt;.&lt;br&gt;&lt;br&gt;
Use the closest location to where you’re from. Then click on Create app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deploy from github
&lt;/h3&gt;

&lt;p&gt;Go on Deploy tab &amp;gt; Deployment method &amp;gt; Connect to Github. Authorize credentials.&lt;br&gt;&lt;br&gt;
You will then have a “App connected to GitHub” section. Write down the repo-name with your own. In this example, mine is still &lt;code&gt;python-server-heroku&lt;/code&gt;. Once the repo is found, click on Connect.&lt;/p&gt;
&lt;h3&gt;
  
  
  Automatic Deploys
&lt;/h3&gt;

&lt;p&gt;Go on Deploy tab &amp;gt; Deployment method &amp;gt; Automatic deploys. Just click on Enable Automatic Deploys.&lt;/p&gt;
&lt;h3&gt;
  
  
  How does it work on Heroku
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Procfile&lt;/code&gt; file will help your app to run on the web and scale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: gunicorn app:app
heroku ps:scale worker=1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test your Heroku App
&lt;/h3&gt;

&lt;p&gt;On the up right corner of your Heroku App Dashboard, click on Open app. If the Hello World statement is displayed, your app is running. Try now to go to &lt;code&gt;&amp;lt;YOUR-HEROKU-APP&amp;gt;.herokuapp.com/&amp;lt;YOUR-DB-HOST&amp;gt;/&amp;lt;YOUR-SELECT-STATEMENT&amp;gt;&lt;/code&gt; and see the datas displaying as JSON object.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Fetch datas into Google Sheets
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create the Spreadsheet
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="//drive.google.com"&gt;drive.google.com&lt;/a&gt; and create a new Google Sheet file. This will lead you to a new tab. Rename the file to whatever you want. Name the first sheet with the same name as your target table. In my case, I will name it &lt;code&gt;conv&lt;/code&gt;. Open a new tab for the next and very last step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create the fetching script
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="//script.google.com"&gt;script.google.com&lt;/a&gt;. Create a new script and save it (the name still doesn’t matter). Paste the following code in &lt;code&gt;Code.gs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const URL_OF_THE_SPREADSHEET = "https://docs.google.com/spreadsheets/d/1QMEr6ABZpLqo8d0h_nY4BCu3hdE0Bkbo-Zj7qgp37Qw/edit#gid=0" //to be changed
const URL_OF_HEROKU_APP = "https://python-server-heroku.herokuapp.com/db.ehbnuyfpyplmhgjshzmd.supabase.co/SELECT%20*%20FROM%20conv" //to be changed
const ss = SpreadsheetApp.openByUrl(URL_OF_THE_SPREADSHEET)

function go(){
  update_my_sheet("conv")
}

function getJSONDataFromUrl(url,params) {
  console.log(url)

  if(!params) params = {}

  params['muteHttpExceptions'] = true
  params['method'] = "GET"

  var response = UrlFetchApp.fetch(url, params);
  var parsedJsonData = JSON.parse(response.getContentText());
  return parsedJsonData;

}

function update_my_sheet(sheet_name){
  var url_to_be_fetched = URL_OF_HEROKU_APP
  var initial_results = getJSONDataFromUrl(url_to_be_fetched)

  //clear everything at the beginning
  var sheet = ss.getSheetByName(sheet_name);
  sheet.getRange(1, 1, sheet.getMaxRows(), sheet.getMaxColumns()).clear({contentsOnly: true});

  //no datas found  
  if(initial_results.length === 0) return false

  var results = initial_results.map(it =&amp;gt; Object.values(it)) 
  var headers = Object.keys(initial_results[0])

  var rows_number = Number(results.length)
  var columns_number = results[0].length

  set_headers(sheet_name, headers)

  //2nd row cause we have the headers in 1st row
  var range = sheet.getRange(2,1,rows_number, columns_number);
  range.setValues(results);


}

function set_headers(sheet_name, headers){
  var last_column_address = columnToLetter(headers.length)
  ss.getSheetByName(sheet_name).getRange("A1:"+last_column_address+"1").setValues([headers]);
}

function columnToLetter(column)
{
  var temp, letter = '';
  while (column &amp;gt; 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt; You will need to change &lt;code&gt;URL_OF_THE_SPREADSHEET&lt;/code&gt; and &lt;code&gt;URL_OF_HEROKU_APP&lt;/code&gt; from the code above.&lt;/p&gt;

&lt;p&gt;Click on &lt;code&gt;go&lt;/code&gt; function from the dropdown menu: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fgo-function.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Fgo-function.PNG" alt="dropdown-functions-google-appscript"&gt;&lt;/a&gt;Run it.&lt;br&gt;&lt;br&gt;
Accept all authorizations.&lt;br&gt;&lt;br&gt;
Go back to your spreadsheet tab, and see the magic! &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ffinal-results.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ffinal-results.PNG" alt="the-magic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  (Optional) Enable a trigger to retrieve datas automatically
&lt;/h3&gt;

&lt;p&gt;Instead of running the &lt;code&gt;go&lt;/code&gt; function manually, you can setup a trigger. Go on the left-side pannel &amp;gt; Triggers. Then configure the parameters as follows, if you want a per-minute refresh for instance: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ftrigger-parameters.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdata-addict.com%2Fassets%2Fimg%2F2021-08-26%2Ftrigger-parameters.PNG" alt="triggers-parameters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it ! Enjoy your datas from Google Sheets directly.&lt;/p&gt;

</description>
      <category>datas</category>
      <category>postgres</category>
      <category>googlesheets</category>
      <category>heroku</category>
    </item>
  </channel>
</rss>
