Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the django_address module provide a way to seed the initial country data?

I'm using Django 2.0, Python 3.7, and MySql 5. I recently installed the django_address module. I noticed when I ran my initial migration based on my models.py file ...

from django.db import models

from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField


class CoopType(models.Model):
    name = models.CharField(max_length=200, null=False)

    class Meta:
        unique_together = ("name",)


class Coop(models.Model):
    type = models.ForeignKey(CoopType, on_delete=None)
    address = AddressField(on_delete=models.CASCADE)
    enabled = models.BooleanField(default=True, null=False)
    phone = PhoneNumberField(null=True)
    email = models.EmailField(null=True)
    web_site = models.TextField()

It created some address tables, including ...

mysql> show create table address_country;
+-----------------+---------------------------------------------------+
| Table           | Create Table                                      |
+-----------------+---------------------------------------------------+
| address_country | CREATE TABLE `address_country` (                  |
|                 |   `id` int(11) NOT NULL AUTO_INCREMENT,           |
|                 |   `name` varchar(40) COLLATE utf8_bin NOT NULL,   |
|                 |   `code` varchar(2) COLLATE utf8_bin NOT NULL,    |
|                 |   PRIMARY KEY (`id`),                             |
|                 |   UNIQUE KEY `name` (`name`)                      |
|                 | ) ENGINE=InnoDB                                   |
|                 | DEFAULT CHARSET=utf8 COLLATE=utf8_bin             |
+-----------------+---------------------------------------------------+

However, this table has no data in it. Is there a way to obtain seed data for the table generated by the module or do I need to dig it up on my own?

like image 309
Dave Avatar asked Jan 27 '20 20:01

Dave


1 Answers

You can generate the countries yourself pretty easily with the pycountry package.

Since the code field on the Country model that is created has a maximum length of two characters then you'll want to use the alpha_2 code.

I usually use a custom management command for this sort of thing. Maybe add a check to see if any objects have already been created then handle as you'd like.

Usage from the shell python manage.py create_countries

from address.models import Country
from pycountry import countries
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = 'Initialize Country model'

    def handle(self, *args, **kwargs):
        create_countries = [
            Country(name=country.name[:40], code=country.alpha_2)
            for country in countries
        ]
        Country.objects.bulk_create(create_countries)
        self.stdout.write(f'Created {len(countries)} countries.\n')

If the production server isn't running Python/Django then you could use pycountry to create a CSV file with the relevant data. Assuming you're using PostgreSQL then you could use the COPY FROM command to populate the database.

import csv
from pycountry import countries

with open('countries.csv', mode='w') as countries_file:
    # specify delimiter because some countries have a comma
    writer = csv.writer(countries_file, delimiter='\t')
    writer.writerow(['id', 'name', 'code'])
    writer.writerows([
        [index + 1, country.name, country.alpha_2]
        for index, country in enumerate(countries)
    ])
like image 145
bdoubleu Avatar answered Oct 09 '22 04:10

bdoubleu