<?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: Data Eng Thailand</title>
    <description>The latest articles on DEV Community by Data Eng Thailand (@dataength).</description>
    <link>https://dev.to/dataength</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%2Forganization%2Fprofile_image%2F1893%2Fb4c73ac5-aa92-4ed0-b7f9-ccb1a4fbdbd1.png</url>
      <title>DEV Community: Data Eng Thailand</title>
      <link>https://dev.to/dataength</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dataength"/>
    <language>en</language>
    <item>
      <title>ใช้ Papermill ทำ Automation กับ Jupyter Notebooks</title>
      <dc:creator>Kan Ouivirach</dc:creator>
      <pubDate>Mon, 07 Sep 2020 08:53:40 +0000</pubDate>
      <link>https://dev.to/dataength/papermill-automation-jupyter-notebooks-n91</link>
      <guid>https://dev.to/dataength/papermill-automation-jupyter-notebooks-n91</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;ในยุคนี้เวลาที่ชาว Data Scientist อยากจะสื่อสารผลที่ได้จากการวิเคราะห์ข้อมูลกับฝั่ง Business หรืออยากที่จะสร้างโมเดลทำนายผลทางธุรกิจสักอย่างหนึ่ง &lt;a href="https://jupyter.org/"&gt;Jupyter Notebooks&lt;/a&gt; จะเป็นอาวุธหรือเครื่องมือสำคัญที่ส่วนใหญ่เราจะหยิบเอามาใช้กัน ซึ่งข้อดีของเครื่องมือตัวนี้ก็คือมันสามารถเป็นทั้ง document เป็น live code รวมไปถึง visualization ภายในตัว&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;แต่อย่างไรก็ดี เครื่องมือตัวนี้ยังมีข้อจำกัดอยู่ที่ว่าเวลาที่เรา&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;อยากจะเปลี่ยนแปลงค่า input บางค่า หรือว่ามีส่วนของโค้ดที่เราอยากไปดึงข้อมูลหลังจากจบเดือนนี้ หรือดึงโค้ดในวันสิ้นปี เราต้องเปิด notebook นั้นๆ ขึ้นมาในวันนั้นๆ แล้วสั่ง execute แต่ละ cell เอง&lt;/li&gt;
&lt;li&gt;อยากจะใช้ค่าจากผลการทดลองที่อยู่ใน notebook ของเพื่อนร่วมทีม สิ่งที่เราต้องทำก็คือไปเปิด notebook ของเพื่อน นั่งไล่ execute แต่ละ cell แล้วก็อปปี้ผลที่ได้มาแปะใน notebook ของเราเพื่อนำค่านั้นๆ ไปใช้งานต่อ&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ทำแค่ครั้งสองครั้งน่าจะยังสบายๆ อยู่ แต่เมื่อไหร่ก็ตามที่เราต้องทำแบบนี้ไปเรื่อยๆ ทุกๆ อาทิตย์ หรือบ่อยกว่านั้น คงจะไม่สนุกแน่ เราควรเอาเวลาไปใช้กับสิ่งที่มีคุณค่ามากกว่านี้ดีกว่า&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Papermill
&lt;/h2&gt;

&lt;p&gt;บทความนี้เลยอยากจะมาแนะนำเครื่องมือ open source ตัวหนึ่งที่ชื่อ &lt;a href="https://papermill.readthedocs.io/"&gt;Papermill&lt;/a&gt; ครับ เค้าว่ามาแบบนี้&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Papermill is a tool for parameterizing and executing Jupyter Notebooks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;หมายความว่าเราสามารถที่จะ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;กำหนด parameters และส่งเข้า notebook ของเราได้&lt;/li&gt;
&lt;li&gt;สั่ง execute ตัว notebook ของเราได้&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;แน่นอนครับ เมื่อเรามีความสามารถแบบนี้ เราจึงสามารถทำ automation หรือจับเอา notebook ของเราเข้าไปรวมอยู่ใน automated workflow ได้แล้วน่ะสิ! ปัญหาที่เอ่ยถึงด้านบนก็ถูกแก้ไขไปเรียบร้อยแล้วด้วยเครื่องมือตัวนี้ครับ&lt;/p&gt;

&lt;p&gt;สิ่งที่ Papermill ทำมีอยู่ 3 ขั้นตอนสั้นๆ คือ&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;รับ notebook มาพร้อมกับ parameters ที่เรากำหนด&lt;/li&gt;
&lt;li&gt;ทำ execute ตัว notebook นั้นๆ ให้&lt;/li&gt;
&lt;li&gt;บันทึกผลลัพธ์ไว้ใน notebook ไฟล์ใหม่&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;อยากลองเล่น? ไปดูหัวข้อถัดไปกันเลย~&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started with Papermill
&lt;/h2&gt;

&lt;p&gt;ติดตั้ง Papermill กับ Jupyter Notebook ก่อนครับ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;papermill jupyter
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;เสร็จแล้วก็ให้เปิด server ของ Jupyter Notebook ขึ้นมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;jupyter notebook
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;เสร็จแล้วก็เขียนโค้ดตามปกติประมาณนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--afl9cyca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sj6fi64ofhwm534gn9zd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--afl9cyca--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/sj6fi64ofhwm534gn9zd.png" alt="Write some code in a Jupyter notebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ต่อไปให้เรากำหนด Tags ให้กับ cell ที่เราอยากให้เป็น parameters ครับ วิธีกำหนดก็ตามรูปด้านล่างนี้เลย กดที่ cell นั้นๆ ก่อน&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AeLDF40h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/naxmsxdniwestzu6v49p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AeLDF40h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/naxmsxdniwestzu6v49p.png" alt="Set up tags for a cell"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ให้เราใส่ tag เป็นคำว่า &lt;code&gt;parameters&lt;/code&gt; ครับ&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Teip9rsX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uwcugwgq3zzdxd7bw7b1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Teip9rsX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uwcugwgq3zzdxd7bw7b1.png" alt='Name the tag "parameters"'&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เสร็จแล้วให้เราไปที่ terminal แล้วสั่ง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;papermill &lt;span class="nt"&gt;-p&lt;/span&gt; name &lt;span class="s1"&gt;'Kan'&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; x 9 &lt;span class="nt"&gt;-p&lt;/span&gt; y 8 main.ipynb output.ipynb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;คำสั่งด้านบนนี้แปลว่าเรากำหนด parameters ตามนี้&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; ให้มีค่าเป็น string มีค่า &lt;code&gt;'Kan'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; ให้เป็น integer มีค่า 9&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;y&lt;/code&gt; ให้เป็น integer มีค่า 8&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;พอรันเสร็จให้เราเปิดไฟล์ notebook ที่เราได้ออกมาใหม่ที่ชื่อ &lt;code&gt;output.ipynb&lt;/code&gt; ดูครับ จะเป็นประมาณนี้&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wLgiLN6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qevk79a622t01dsxo50o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wLgiLN6P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qevk79a622t01dsxo50o.png" alt="Output from the execution using Papermill"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;เห็นได้ว่า Papermill มาแทรก cell ที่มี tag ชื่อ &lt;code&gt;injected-parameters&lt;/code&gt; ไว้ข้างใต้ cell ของเราที่ tag ไว้ก่อนหน้านี้ ซึ่งทำให้ cell ถัดๆ ไปได้ใช้ค่า parameters ที่โดน inject เข้าไปแทนที่จะใช้ parameters ที่เรากำหนดไว้ตอนแรก&lt;/p&gt;

&lt;p&gt;ดูเป็นวิธีที่ simple มากๆ แต่แก้ปัญหาได้เยอะเลยนะ งดงามมาก&lt;/p&gt;

&lt;p&gt;ใครอยากเห็นโค้ดที่ใช้ในบทความนี้ ตามไปดูกันได้ที่ &lt;a href="https://github.com/zkan/hello-papermill"&gt;hello-papermill&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ใครที่ใช้ Papermill กันอยู่ อยากรู้จังว่าเอาไปใช้ใน use case ไหนกันบ้าง แชร์กันมาได้นะครับ ^^&lt;/p&gt;

&lt;p&gt;ปล. ถ้าเราไม่ tag คำว่า &lt;code&gt;parameters&lt;/code&gt; ที่ cell ของเราไว้ Papermill จะใส่ &lt;code&gt;injected-parameters&lt;/code&gt; ไว้ที่ cell ด้านบนสุดให้&lt;/p&gt;

</description>
      <category>jupyter</category>
      <category>papermill</category>
      <category>automation</category>
    </item>
    <item>
      <title>5 Challenges ในการสร้าง Production-Grade Data Pipeline</title>
      <dc:creator>Kan Ouivirach</dc:creator>
      <pubDate>Sat, 20 Jun 2020 01:58:51 +0000</pubDate>
      <link>https://dev.to/dataength/5-challenges-production-grade-data-pipeline-1p06</link>
      <guid>https://dev.to/dataength/5-challenges-production-grade-data-pipeline-1p06</guid>
      <description>&lt;p&gt;เวลาที่มีคนมาปรึกษาว่าอยากจะลงมือสร้าง data pipeline จะเริ่มสร้างอย่างไร ส่วนใหญ่ผมมักจะชวนให้ลองทำ data pipeline แบบ minimal ขึ้นมาก่อน โดยการเขียน script ประมาณนี้&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ดึงข้อมูลอะไรก็ได้ที่ดูน่าสนใจจากอินเตอร์เนท หรือจากเว็บ &lt;a href="https://data.go.th/"&gt;Open Government Data of Thailand&lt;/a&gt; ออกมาเก็บอยู่ในฟอร์แมตสักฟอร์แมตหนึ่ง เช่น CSV&lt;/li&gt;
&lt;li&gt;จัดการทำความสะอาดข้อมูลสักเล็กน้อย เช่น คอลัมน์ปีเกิด อาจจะเก็บค่าปีเป็น พ.ศ. บ้าง ค.ศ. บ้าง เราก็แปลงให้เป็นปีแบบเดียวกัน หรือพวก timestamp ก็จัดฟอร์แมตให้เราเอาไปใช้ต่อได้ง่าย&lt;/li&gt;
&lt;li&gt;สร้างฐานข้อมูลขึ้นมาสัก 1 เครื่อง แล้วโหลดข้อมูลเข้าไป&lt;/li&gt;
&lt;li&gt;กำหนดให้ script ถูกรันทุกๆ วันตอนเที่ยงคืน หรือทุกๆ 5 นาทีก็ได้นะ&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;ที่ว่ามาด้านบนนี้คืออยากให้คนที่เพิ่งเริ่มต้นได้ feeling เบื้องต้นของสายงานด้าน data engineering เรียกได้ว่ามันคือการสร้าง data pipeline แบบ happy path เฉยๆ ทีนี้ถ้าเราจะต่อยอดไปจากนี้ แล้วสร้างให้ดีๆ เราจะเจอความท้าทาย 5 อย่างประมาณนี้ลองไปดูกัน&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Schema เปลี่ยนแปลงอยู่ตลอด
&lt;/h2&gt;

&lt;p&gt;อันนี้น่าจะเป็นปัญหาอันดับ 1 ที่ทุกคนต้องเจอ ยิ่งในยุคปัจจุบันที่โลกของซอฟต์แวร์นั้นเปลี่ยนแปลงไปเร็วมาก disrupt กันเป็นว่าเล่น ธุรกิจเราก็ evolve ตามไป และแน่นอนว่าจะส่งผลให้ schema ของข้อมูลนั้นเปลี่ยนแปลงไป เราก็ต้องปรับ data pipeline ของเราตาม&lt;/p&gt;

&lt;p&gt;วิธีการก็มีอยู่หลายวิธีขึ้นอยู่กับสถานการณ์ เช่น ถ้าข้อมูลเราไม่เยอะเท่าไหร่ แล้วการวิเคราะห์ข้อมูลก็ไม่จำเป็นต้องเป็น real-time เราอาจจะ drop table ทิ้ง สร้างใหม่ แล้วโหลดข้อมูลตามไปก็ได้อยู่นะ แต่ถ้าข้อมูลเราเยอะมากขึ้น การทำแบบนี้ก็อาจจะเสียเวลาไปเป็นวันๆ เราก็ต้องหาวิธีอื่นมาแก้ปัญหา เป็นต้น&lt;/p&gt;

&lt;p&gt;ระบบ monitoring กับ logging ดีๆ จะช่วยให้เรารู้ตัวได้ไว และการทำ schema version management ก็สามารถช่วยได้เช่นกัน 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Machine Failure เป็นเรื่องปกติ
&lt;/h2&gt;

&lt;p&gt;งาน data pipeline ไม่ได้มีแค่ส่วนโค้ดที่เราต้องดูแล ยังมีเรื่องของ infrastructure ที่เราใช้อยู่ด้วย ระบบหรือตัวเครื่องเซิฟเวอร์ก็จะมีปัญหาประมาณว่า disk เต็ม เขียนไฟล์ไม่ได้บ้าง เครื่องค้างต้องรีสตาร์ท ระบบ network หรือ DNS ล่ม แล้วยังต้องอัพเกรด patch อีก สิ่งเหล่านี้เกิดขึ้นเป็นเรื่องปกติ 🤣 หาวิธีรับมือไว้เลยแต่เนิ่นๆ&lt;/p&gt;

&lt;h2&gt;
  
  
  3. การ Scale เพื่อรองรับข้อมูลที่มีขนาดใหญ่ขึ้นเรื่อยๆ
&lt;/h2&gt;

&lt;p&gt;ช่วงแรกๆ ตอนที่มีข้อมูลน้อยๆ เราก็ happy ดีแหละ data pipeline อาจจะใช้เวลาไม่ถึง 10 นาทีก็ทำงานเสร็จ 😊 แต่หลายๆ คน รวมถึงตัว business เอง เรื่องการ scale ตัว data pipeline อาจจะไม่ใช่ priority ขององค์กร เลยไม่ได้นึกถึงเรื่องการ scale เท่าไหร่ ตรงนี้ผมมองว่ามันจะเป็นหลุมพลาง (pitfall) เนื่องจากข้อมูลที่ไหลเข้ามา และเพิ่มขึ้นเรื่อยๆ การทำงานของ data pipeline ก็จะใช้เวลานานขึ้นเรื่อยๆ เช่นกัน ยังไม่จบแค่นั้น.. แต่ละองค์กรก็คงไม่ได้มีแค่ pipeline เดียวแน่ ยิ่งปล่อยทิ้งไว้มันก็ยิ่งเหมือน technical debt ที่สะสม ไปจนวันหนึ่งเราจะไม่สามารถแก้มันได้อีกแล้ว เพราะ cost ของ effort ที่จะลงแรงไปปรับปรุงให้ดีขึ้นมันสูงเกินไป&lt;/p&gt;

&lt;p&gt;ดังนั้นให้นึกถึงการ scale เอาไว้ด้วยเลย ยิ่งองค์กรไหนมีข้อมูลเยอะอยู่แล้ว เรื่องการ scale เป็นเรื่องที่สำคัญมาก ตรงนี้จะรวมไปถึงการเลือก technology ที่เหมาะสมมาใช้ด้วยเช่นกัน ใช้แค่ script อย่างที่กล่าวไว้ตอนต้นอย่างเดียวคงจะไม่พอล่ะ&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Batch vs. Real-Time
&lt;/h2&gt;

&lt;p&gt;เรื่องนี้ก็ตาม business เลย ขึ้นอยู่กับ context ของแต่ละที่ และแต่ละงาน ถึงแม้ว่าตลาดส่วนใหญ่จะเป็นเรื่อง batch processing แต่ก็อยากให้ระลึกไว้เสมอไว้ว่างานในหลายๆ ที่มีแบบ real-time processing เข้ามาแล้ว การทำ data pipeline แบบ batch กับแบบ real-time ก็มีการพัฒนาและการดูแลที่แตกต่างกัน พวกเราชาว data engineer ควรที่จะศึกษาและลองเล่นไว้ทั้ง 2 แบบนะ 🤓&lt;/p&gt;

&lt;h2&gt;
  
  
  5. การทำ Data Catalog และ Data Lineage
&lt;/h2&gt;

&lt;p&gt;หัวข้อนี้มีความเกี่ยวข้องกับการทำ data lake ด้วยนะ ซึ่งหลายคนมักจะมองข้าม เอาไว้ทำทีหลังก็ได้ แล้วสุดท้ายก็จะลืม.. หรือไม่ก็เกิดอาการ curse of knowledge ของคนทำข้อมูล ที่ว่ามองแว๊บเดียวก็รู้ว่าอะไรคืออะไร อย่าไปตกหลุมพลางเข้าล่ะ ระลึกไว้เสมอเลยว่าเราไม่ได้ทำงานคนเดียว 🙂&lt;/p&gt;

&lt;p&gt;ก็อยากจะมาเขียนย้ำครับว่าให้นึกถึงการทำ data catalog (เก็บ metadata ไว้เพื่อให้ค้นหาข้อมูลได้สะดวกและรวดเร็ว) กับ data lineage (รู้ที่มาที่ไปของข้อมูลว่ามาจากไหน ได้มาได้อย่างไร โดน transform มาแบบไหน) ด้วย &lt;/p&gt;

&lt;h2&gt;
  
  
  สรุปช่วงท้าย
&lt;/h2&gt;

&lt;p&gt;ที่เขียนไว้ด้านบนน่าจะเป็นความท้าทายที่คนทำงานทางด้านข้อมูล โดยเฉพาะสายงาน data engineer 👷🏻‍♀️👷🏻‍♂️ น่าจะต้องเจอกัน งานสร้าง data pipeline ให้ดีๆ ก็จะมีหลายอย่างที่ต้องคิด แล้วก็จะมีอีกหลายอย่างที่เราอาจจะต้องไปเจอหน้างาน แล้วแก้ไปตาม context ณ ตอนนั้นด้วย 😅&lt;/p&gt;

&lt;p&gt;คนที่แวะเข้ามาได้เจอความท้าทายอะไรกันบ้างเอ่ย? เล่าให้อ่านกันได้นะ 😘&lt;/p&gt;

&lt;p&gt;ปล. ขอบคุณรูป cover สวยๆ จาก &lt;a href="https://unsplash.com/@jjying?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;JJ Ying&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>datapipeline</category>
    </item>
  </channel>
</rss>
