<?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: ODDS</title>
    <description>The latest articles on DEV Community by ODDS (@odds-team).</description>
    <link>https://dev.to/odds-team</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%2F2073%2Fb0e289d6-04cf-439a-a21f-2cdce651f752.jpg</url>
      <title>DEV Community: ODDS</title>
      <link>https://dev.to/odds-team</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/odds-team"/>
    <language>en</language>
    <item>
      <title>Backup Django ง่ายกว่านี้ไม่มีอีกแล้วด้วย django-dbbackup</title>
      <dc:creator>Yothin M</dc:creator>
      <pubDate>Sun, 17 May 2020 05:17:58 +0000</pubDate>
      <link>https://dev.to/odds-team/backup-django-django-dbbackup-3adf</link>
      <guid>https://dev.to/odds-team/backup-django-django-dbbackup-3adf</guid>
      <description>&lt;p&gt;ช่วงนี้ผมต้องมาขึ้น Django project ใหม่กับทีมครับ ซึ่งพอขึ้น Project ใหม่ หนึ่งใน Development workflow ที่มาคู่กันคือ การต้องเอา Database จาก Production กลับมาใช้ที่ Local development ให้ได้ เพื่อที่จะ debug ปัญหาหลายๆ อย่างได้กับ Data บน Production หรือ เพื่อความสะดวกสบายในการ Development ครับ&lt;/p&gt;

&lt;p&gt;ทีนี้ที่ผ่านมามันไม่ค่อยมีปัญหาเพราะ Database ผมมักจะใช้ PostgreSQL ซึ่งอาจจะอยู่ใน database Instance ของตัวเอง อยู่บน Container ของตัวเอง ฯลฯ ซึ่งก็ใช้ &lt;code&gt;pg_dump&lt;/code&gt; กับ &lt;code&gt;pg_restore&lt;/code&gt; คู่กันง่ายๆ มาตลอด ไม่มีปัญหายเว้นอัพเกรด PostgreSQL major version ที่ไฟล์ format เปลี่ยนนิดหน่อยก็ตามอัพเกรด client กัน&lt;/p&gt;

&lt;p&gt;ปัญหามันอยู่ที่ Media files ครับ ซึ่งถ้าเลือกได้ ผมจะเลือกใช้ &lt;a href="https://github.com/jschneier/django-storages"&gt;django-storages&lt;/a&gt; เพื่อที่จะ offload ตัว media file ไปเก็บไว้ใน object storage เช่น Amazon s3 หรือ Google Cloud Storage ครับ แต่ใน use case ที่เราเลือกไม่ได้ต้องเก็บไฟล์ลง server เท่านั้น เราจะทำยังไงหละ&lt;/p&gt;

&lt;p&gt;พอมี Use case แบบนี้แวบแรกที่ผมคิดออกคือ &lt;code&gt;rsync&lt;/code&gt; เลยครับ ง่ายๆ บ้านๆ sync directory ที่ต้องเก็บ Media กลับมาลงใน local  แต่ผมตั้งคำถามกับตัวเองว่ามันมีวิธีอื่นมั้ย มันเลยเกิด post นี้ขึ้นนี่แหละครับ&lt;/p&gt;

&lt;h2&gt;
  
  
  Django Database Backup
&lt;/h2&gt;

&lt;p&gt;ผมค้นไปเจอ &lt;a href="https://django-dbbackup.readthedocs.io/en/stable/index.html"&gt;django-dbbackup&lt;/a&gt; เพราะคิดว่าจะทำยังไงถึงจะ backup database / media files ได้พร้อมกันเลย ไม่ต้องมานั่งทำทีละอย่าง เรียกได้ว่า รันคำสั่งเดียวปุ๊ปได้ Data พร้อมใช้งานใน local เลย ซึ่งสารภาพว่าแวบแรกก็นึกว่าจะเขียน Ansible playbook ไปเลย แต่ถ้าทีมไม่ได้มี Technical ลึกหละ&lt;/p&gt;

&lt;p&gt;ตัว Django  Database Backup นี่เป็น Package ที่ไม่ได้ซับซ้อนอะไรเลยครับ ไม่ได้ Reinvent the wheel การ backup ขึ้นมาใหม่ เป็นไอเดียง่ายๆ แค่ dump / restore ไฟล์ อาจจะรวม compresion กับ encryption ขึ้นมานิดหน่อย แต่ไม่ได้สลับซับซ้อนอะไรเลย โดยตัว Package จะเป็น extension app ของ Django ที่ provide management command ต่างๆ มาให้เราทำงานได้ง่ายขึ้นครับ&lt;/p&gt;

&lt;p&gt;วิธีลงไม่ยากแค่สั่ง pip install django-dbbackup หรือจะเพิ่ม dependencies ลงใน requirements.txt, Pipfile, pyproject.toml เอาที่สะดวกเลยครับ พอลงเสร็จแล้วมีจุดที่เราต้อง config เบื้องต้นเพิ่มใน Django settings file เรา 2 อย่าง&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;อย่างแรกเลยคือให้เราเพิ่ม INSTALLED_APPS ชื่อ dbbackup ลงไปครับ ซึ่งจะเอาไว้ตรงไหนก็ได้ order ไม่สำคัญ&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;INSTALLED_APPS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="s"&gt;'dbbackup'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# django-dbbackup
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;อย่างที่สองคือ เราต้องเพิ่ม settings เพื่อที่จะบอกว่า Backup เราเนี่ยจะเก็บไว้ที่ไหน​ซึ่งสามารถเก็บไว้ได้ทั้ง Amazon S3, Dropbox, FTP แต่ในเคสง่ายๆ เราเก็บไว้ใน File System ในโปรเจ็คเราก็ได้ครับหน้าตาประมาณนี้&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DBBACKUP_STORAGE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'django.core.files.storage.FileSystemStorage'&lt;/span&gt;
&lt;span class="n"&gt;DBBACKUP_STORAGE_OPTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;'location'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'/app/backups'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;ตรงจุดนี้ระวังนิดนึงนะครับมี bug ใน document ตรง DBBACKUP_STORAGE มันจะชี้ไปที่ &lt;code&gt;dbbackup.storage.filesystem_storage&lt;/code&gt; ซึ่งที่ถูกต้องคือ &lt;code&gt;django.core.files.storage.FileSystemStorage&lt;/code&gt; ครับ&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;หลังจากที่เราติดตั้งเสร็จแล้ว config เสร็จแล้วทีนี้เราก็สามารถใช้งาน Django database backup ได้แล้วครับ ซึ่งมันไม่ได้แค่ backup database ตามชื่อ แต่ครอบคลุมไปถึง Media ด้วย&lt;/p&gt;

&lt;h3&gt;
  
  
  Backup / restore Media
&lt;/h3&gt;

&lt;p&gt;ถ้าเราจะ Backup ตัว Media file เราก็ใช้ management command &lt;code&gt;mediabackup&lt;/code&gt; ได้เลยครับตัว output จะออกมาคล้ายๆ ตัวอย่างข้างล่างเลย คือเป็นไฟล์ compress ของ media ใน Django app เราครับ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py mediabackup
Writing file to 7b23e710c576-2020-05-17-044731.tar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ส่วนถ้าเราอยากจะ restore ก็แค่ใช้ command &lt;code&gt;mediarestore&lt;/code&gt; ครับ ซึ่งสามารถเลือกไฟล์เองก็ได้ แต่ถ้า structure ของไฟล์ไม่ต่างกันเราสามารถเรียกได้เลยครับ แล้วตัว Django dbbackup มันฉลาดพอจะเลือกไฟล์ล่าสุดมา restore ครับ รวมถึงถ้าไม่มี directory ก็จะสร้างให้หมดเลยด้วย&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py mediarestore
Restoring backup &lt;span class="k"&gt;for &lt;/span&gt;media files
Finding latest backup
Restoring: 7b23e710c576-2020-05-17-044843.tar
Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;? &lt;span class="o"&gt;[&lt;/span&gt;Y/n] Y
some_media_path/image1.png uploaded
some_media_path/image2.png uploaded
some_media_path/image3.png uploaded
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Backup / Restore Database
&lt;/h3&gt;

&lt;p&gt;ในส่วนของ Backup database จะมีความยุ่งยากกว่า Media นิดนึงตรงที่เราต้องมี client ของ Database ตัวนั้นจริงๆ อยู่ในเครื่องที่เราจะรัน command นี้ด้วยครับเช่น เคสผมใช้ PostgreSQL ก็ต้องมี &lt;code&gt;postgresql-client&lt;/code&gt; ในเครื่องก่อน มันถึงจะพาเพื่อนอย่าง &lt;code&gt;pg_dump&lt;/code&gt;, &lt;code&gt;pg_restore&lt;/code&gt; มาด้วย แต่ข้อควรระวังอีกอย่างคือ ลง postgrsql-client ให้มันตรงกับ version PosgreSQL ที่เราใช้ด้วยนะครับ ในเคสนี้ผมแค่สั่ง &lt;code&gt;apt install postgresql-client-12&lt;/code&gt; ก็เรียบร้อยครับ &lt;/p&gt;

&lt;p&gt;พอเรามี client ในเครื่องแล้วที่เหลือก็ง่ายเลย แทนที่เราจะต้องมาสั่ง pg_dump ด้วย option ยาวๆ เราก็ใช้ management command &lt;code&gt;dbbackup&lt;/code&gt; สั่ง โดยตัว Django dbbackup ก็จะไปดูด database settings &lt;/p&gt;

&lt;p&gt;ของเรามา fill ให้ไม่ต้องมาจำเอง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python &lt;span class="o"&gt;[&lt;/span&gt;manage.py]&lt;span class="o"&gt;(&lt;/span&gt;http://manage.py/&lt;span class="o"&gt;)&lt;/span&gt; dbbackup
Backing Up Database: postgres
Writing file to default-7b23e710c576-2020-05-17-050714.psql
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ส่วนวิธี restore ก็จะเก่งเหมือน Media restore ที่รู้จักไฟล์ล่าสุดครับ ส่วน command ก็สั้นๆ แค่ &lt;code&gt;dbrestore&lt;/code&gt; พอสั่งเสร็จเราก็ได้ database backup มาใช้ละ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python manage.py dbrestore
Finding latest backup
Restoring backup &lt;span class="k"&gt;for &lt;/span&gt;database &lt;span class="s1"&gt;'default'&lt;/span&gt; and server &lt;span class="s1"&gt;'None'&lt;/span&gt;
Restoring: default-7b23e710c576-2020-05-17-050714.psql
Restore tempfile created: 62.2 KiB
Are you sure you want to &lt;span class="k"&gt;continue&lt;/span&gt;? &lt;span class="o"&gt;[&lt;/span&gt;Y/n] Y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;จบแล้วครับ ง่ายๆ แค่นี้เลย จริงๆ ตัว Django dbbackup ยังทำอย่างอื่นได้อีกทั้ง encryption , filename prefix หรือ จะตั้ง limit ให้เก็บแค่กี่ไฟล์ล่าสุดก็ได้ ก็ลองอ่านได้ใน Documentation ครับเขียนไว้ค่อนข้างอ่านง่ายเลย ก็หวังว่าชีวิตจะง่ายขึ้นกันนะครับ หลังจากนี้ 🐍🐮&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/django-dbbackup/django-dbbackup"&gt;https://github.com/django-dbbackup/django-dbbackup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://django-dbbackup.readthedocs.io/en/stable/"&gt;https://django-dbbackup.readthedocs.io/en/stable/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>database</category>
      <category>devops</category>
      <category>python</category>
    </item>
  </channel>
</rss>
