Django standalone script to take database backup
Tags: django, webdev, databasebackup, djangostandalonescript
Published: 2021-05-06 06:00:26

In this blog we will learn to write standalone script which will be a generalized script to convert entire database to csv/xls files etc.

Standalone script is basically a script where you don’t need to run server. It is “stand alone” i.e it is capable of performing tasks without any other requirement.

>This blog was initially published on https://www.gyaanibuddy.com/blog/django-standalone-script-to-take-database-backup/

###Prerequisites
A django project with any database along with some models whose data you wish to take backup.

###Basic template
This code is going to be the bare minimum skeleton of our script.
1. Create a script.py file in the same directory as manage.py file.
2. Paste the below code snippet.
3. Rename PROJECT_NAME to your project’s name

```
import os
PROJECT_NAME = 'ENTER YOUR PROJECT NAME HERE'

def main():
    # import statemts
    # from app.models import Author,Category,Book
    
    # code logic - anything you want
    

if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', '%s.settings' % PROJECT_NAME)
    import django
    django.setup()
    main()
```

Run the code by entering `python script.py`

If it ran with no errors then you are good to go. If you have any error, then depending on error you may have path error, installed app error etc.

###Backup script
If you are only interested in the script, scroll to the bottom and just paste it in script.py and run it.

Lets look at some of the basic functions which will help us get the script ready.

* Firstly, we need list of all the models.
```
from django.apps import apps 
model_list = apps.get_models() 
model_name_list = [x.__name__ for x in model_list]
```

* Now that we have the model, we will iterate over every single table and get its schema i.e the columns (or fields) in the table. We need the field/column names so that we can write them as column names to csv/xls file.
```
for model in model_list:
    all_fields = model._meta.get_fields()
    columns = [x.name for x in all_fields]
```

* Lets iterate over entire database and write the data to csv/xls.
```
with open(f'csvs/{model.__name__}.csv', mode='w') as csv_file:
  writer = csv.writer(csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
  # Writing column names
  writer.writerow(columns)
  objects = model.objects.all()
            
  for obj in objects:
    row = [str(getattr(obj, field_name,"NA")) for field_name in columns]
    writer.writerow(row)
```

* You will observe that a csv folder is created and inside it will contain one csv file for every table. So if you have Author, Book as tables, you will have Author.csv and Book.csv saved in the csv folder in the project root directory.
```
'''
django standalone script to take backup of database in the form of csvs for each model.
- Place it in the same directory as manage.py file
- Rename PROJECT_NAME to your project's name
'''

import os

PROJECT_NAME = '--- ENTER YOUR PROJECT NAME HERE ---'

def main():
    from django.apps import apps
    import csv

    model_list = apps.get_models()
    model_name_list = [x.__name__ for x in model_list]
    
    for model in model_list:
        all_fields = model._meta.get_fields()
        columns = [x.name for x in all_fields]
        
        if not os.path.exists('csvs'):
            os.makedirs('csvs')

        with open(f'csvs/{model.__name__}.csv', mode='w') as csv_file:
            writer = csv.writer(csv_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
            
            # Writing column names
            writer.writerow(columns)

            objects = model.objects.all()
            
            for obj in objects:
                row = [str(getattr(obj, field_name,"NA")) for field_name in columns]
                writer.writerow(row)
    
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', '%s.settings' % PROJECT_NAME)
    import django
    django.setup()
    main()
```

Based on your preference you can store the database in any form (Eg. sqlite,xls,csv,json etc). In the above script i have created a “csv” folder and inside it contains individual csv file for each model. Each csv will contain data of one model and will have column name as field names and each row will be single entry of that specific model.


Yayy! That’s all you need to do to write standalone script in django to take backup of database.