title: Reading S3 files in nested directory through Spark EMR
body: <p>I figured out how to read files into my pyspark shell (and script) from an S3 directory, e.g. by using:</p>
  
  <pre><code>rdd = sc.wholeTextFiles('s3n://bucketname/dir/*')
  </code></pre>
  
  <p>But, while that's great in letting me read all the files in ONE directory, I want to read every single file from all of the directories. </p>
  
  <p>I don't want to flatten them or load everything at once, because I will have memory issues. </p>
  
  <p>Instead, I need it to automatically go load all the files from each sub-directory in a batched manner. Is that possible?</p>
  
  <p>Here's my directory structure:</p>
  
  <p>S3_bucket_name -> year (2016 or 2017) -> month (max 12 folders) -> day (max 31 folders) -> sub-day folders (max 30; basically just partitioned the collecting each day). </p>
  
  <p>Something like this, except it'll go for all 12 months and up to 31 days...</p>
  
  <pre><code>BucketName
  |
  |
  |---Year(2016)
  |       |
  |       |---Month(11)
  |       |      |
  |       |      |---Day(01)
  |       |      |      |
  |       |      |      |---Sub-folder(01)
  |       |      |      |
  |       |      |      |---Sub-folder(02)
  |       |      |      |
  |       |      |---Day(02)
  |       |      |      |
  |       |      |      |---Sub-folder(01)
  |       |      |      |
  |       |      |      |---Sub-folder(02)
  |       |      |      |
  |       |---Month(12)
  |
  |---Year(2017)
  |       |
  |       |---Month(1)
  |       |      |
  |       |      |---Day(01)
  |       |      |      |
  |       |      |      |---Sub-folder(01)
  |       |      |      |
  |       |      |      |---Sub-folder(02)
  |       |      |      |
  |       |      |---Day(02)
  |       |      |      |
  |       |      |      |---Sub-folder(01)
  |       |      |      |
  |       |      |      |---Sub-folder(02)
  |       |      |      |
  |       |---Month(2)
  </code></pre>
  
  <p>Each arrow above represents a fork. e.g. I've been collecting data for 2 years, so there are 2 years in the "year" fork. Then for each year, up to 12 months max, and then for each month, up to 31 possible day folders. And in each day, there will be up to 30 folders just because I split it up that way...</p>
  
  <p>I hope that makes sense...</p>
  
  <p>I was looking at another post (<a href="https://stackoverflow.com/questions/27914145/read-files-recursively-from-sub-directories-with-spark-from-s3-or-local-filesyst">read files recursively from sub directories with spark from s3 or local filesystem</a>) where I believe they suggested using wildcards, so something like:</p>
  
  <pre><code>rdd = sc.wholeTextFiles('s3n://bucketname/*/data/*/*') 
  </code></pre>
  
  <p>But the problem with that is it tries to find a common folder among the various subdirectories - in this case there are no guarantees and I would just need everything. </p>
  
  <p>However, on that line of reasoning, I thought what if I did..:</p>
  
  <pre><code>rdd = sc.wholeTextFiles("s3n://bucketname/*/*/*/*/*')
  </code></pre>
  
  <p>But the issue is that now I get OutOfMemory errors, probably because it's loading everything at once and freaking out.</p>
  
  <p>Ideally, what I would be able to do is this:</p>
  
  <p>Go to the sub-directory level of the day and read those in, so e.g.</p>
  
  <p>First read in 2016/12/01, then 2016/12/02, up until 2012/12/31, and then 2017/01/01, then 2017/01/02, ... 2017/01/31 and so on. </p>
  
  <p>That way, instead of using five wildcards (*) as I did above, I would somehow have it know to look trough each sub-directory at the level of "day". </p>
  
  <p>I thought of using a python dictionary to specify the file path to each of the days, but that seems like a rather cumbersome approach. What I mean by that is as follows:</p>
  
  <pre><code>file_dict = { 
      0:'2016/12/01/*/*', 
      1:'2016/12/02/*/*', 
      ...
      30:'2016/12/31/*/*',
  }
  </code></pre>
  
  <p>basically for all the folders, and then iterating through them and loading them in using something like this:</p>
  
  <pre><code>sc.wholeTextFiles('s3n://bucketname/' + file_dict[i])
  </code></pre>
  
  <p>But I don't want to manually type out all those paths. I hope this made sense...</p>
  
  <p>EDIT:</p>
  
  <p>Another way of asking the question is, how do I read the files from a nested sub-directory structure in a batched way? How can I enumerate all the possible folder names in my s3 bucket in python? Maybe that would help...</p>
  
  <p>EDIT2:</p>
  
  <p>The structure of the data in each of my files is as follows:</p>
  
  <pre><code>{json object 1},
  {json object 2},
  {json object 3},
  ...
  {json object n},
  </code></pre>
  
  <p>For it to be "true json", it either just needed to be like the above without a trailing comma at the end, or something like this (note square brackets, and lack of the final trailing comma:</p>
  
  <pre><code>[
     {json object 1},
     {json object 2},
     {json object 3},
     ...
     {json object n}
   ]
  </code></pre>
  
  <p>The reason I did it entirely in PySpark as a script I submit is because I forced myself to handle this formatting quirk manually. If I use Hive/Athena, I am not sure how to deal with it. </p>