4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Django] ローカルのsqlite3からHerokuのPostgreSQLにデータを移行する

Last updated at Posted at 2018-10-06

経緯

オープンデータを使ってDjangoでWebアプリケーションを作ろうと思い
csvファイルをsqlite3にインポートしました。
Herokuにデプロイしようとしたら
sqlite3が使えなかったのでローカルに登録したデータを
PostgreSQLに移行するまでのメモです。

csvファイルをインポート

文京区の保育園の一覧をダウンロードしました。
事前にNULLを0に置換するなどデータを加工しておきました。
http://opendata-catalogue.metro.tokyo.jp/dataset/t131059d0206080001

sqlite3 DBファイル名 で起動

$ sqlite3 db.sqlite3

カラムの区切り文字を変更

sqlite> .separator ,

.import csvファイル名 テーブル名でインポート

sqlite> .import hoikuen.csv hoikuen

参考:sqlite3でcsvファイルからインポート

アプリケーションのテーブルにインサート

「hoikuen」テーブルからアプリケーションのデータを登録する「app_item」テーブルに必要なデータだけをインサートしました。
Djangoモデルは以下のとおりです。(バリデーションはまだ実装してないです。)

models.py
from django.db import models

class Item(models.Model):

    CATEGORIES1 = (
        (1, '区立保育園'),
        (2, '私立保育園'),
    )

    CATEGORIES2 = (
        (1, '認可保育園'),
        (2, '認証保育園'),
        (3, '認定こども園'),
        (4, '認可外保育施設'),
    )

    name = models.CharField(
        verbose_name='施設名',
        max_length=200,
    )

    postal_code = models.CharField(
        max_length=8,
        verbose_name='郵便番号'
        )

    address = models.TextField(
        verbose_name='住所',
        max_length=300,
        blank=True
   )

    latitude = models.DecimalField(
        verbose_name='緯度',
        max_digits=9, 
        decimal_places=6, 
        default=0
    )
        
    longitude = models.DecimalField(
        verbose_name='経度', 
        max_digits=9, 
        decimal_places=6, 
        default=0
    )

    tel_number = models.CharField(
        max_length=15, 
        verbose_name='電話番号'
    )

    category1 = models.IntegerField(
        verbose_name='カテゴリ1',
        choices=CATEGORIES1,
        default=1
    )

    category2 = models.IntegerField(
        verbose_name='カテゴリ2',
        choices=CATEGORIES2,
        default=1
    )

    total = models.IntegerField(
        verbose_name='合計',
        default=0
    )

    year0 = models.IntegerField(
        verbose_name='0歳',
        default=0
    )

    year1 = models.IntegerField(
        verbose_name='1歳',
        default=0
    )
    year2 = models.IntegerField(
        verbose_name='2歳',
        default=0
    )

    year3 = models.IntegerField(
        verbose_name='3歳',
        default=0
    )

    year4_5 = models.IntegerField(
        verbose_name='4・5歳',
        default=0
    )

    created_at = models.DateTimeField(
        verbose_name='登録日',
        auto_now_add=True
    )
    
    # 以下は管理サイト上の表示設定
    def __str__(self):
        return self.name
import.sql
INSERT INTO app_item 
SELECT "No.",施設名,郵便番号,住所,緯度,経度,電話番号,
 CASE
    WHEN カテゴリ1='区立保育園' THEN '1' 
    WHEN カテゴリ1='私立保育園' THEN '2' 
    ELSE '0'
  END,
 CASE 
    WHEN カテゴリ2='認可保育園' THEN '1'
    WHEN カテゴリ2='認証保育園' THEN '2'
    WHEN カテゴリ2='認定こども園' THEN '3'
    WHEN カテゴリ2='認可外保育施設' THEN '4'   
    ELSE '0'
  END,
 合計園児定員(名),0歳児定員(名),1歳児定員(名),2歳児定員(名),3歳児定員(名),4・5歳児定員(名),
 DATETIME('now', 'localtime')
FROM hoikuen;

csvファイルにエクスポート

herokuデプロイしたものの、登録したデータが空になってしまったのでsqlite3からPostgreSQLにデータを移行します。
(最初からモデルに合わせてcsvを加工しておけばよかったです。)

sqlite>  .mode csv
sqlite>  .output output.csv
sqlite>  SELECT * FROM app_item;

HerokuのDBに接続

Homebrewを使用してPostgreSQLをインストール

$ brew install postresql

参考:MacにHomebrewでPostgreSQLをインストール

Heroku CLIをインストール

$ brew install heroku/brew/heroku

HerokuのPostresSQLへ接続

$ heroku pg:psql

参考:HerokuのDBにローカルPCからアクセスしたいんだけど...

csvファイルをインポート
\COPY テーブル名 FROM 'csvファイル名' WITH CSV

DATABASE=> \COPY app_item FROM 'output.csv' WITH CSV
4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?