はじめに
Djangoを使ってお酒のECサイトを作っています。
商品のデータをCSVでインポートしようとした際にエラーと戦ったので、その時に調べた解決策を書いた記事になります。
Django2
PostgreSQL
やりたかったこと
インポートする前に2つのテーブルを作成した。
一つは商品の分類をするCategoryテーブル。もう一つは商品情報のProductテーブル。
# Metaタグなどは省略
class Category(models.Model):
name = models.CharField(max_length=250, unique=True)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(blank=True)
image = models.ImageField(upload_to='category', blank=True)
class Product(models.Model):
name = models.CharField(max_length=250, unique=True)
slug = models.SlugField(max_length=250, unique=True)
description = models.TextField(blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)#★今回問題のやつ★
price = models.IntegerField()
image = models.ImageField(upload_to='product', blank=True)
stock = models.IntegerField()
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True, null=True)
インポートしたいCSVファイルは以下。
- Category.csv
このCSVファイルをインポートしてテーブルに入れることが目標
出てきたエラー
まずはCategory.csvをインポートした。
practice_db=> \copy shop_product (name,slug,description,image) FROM 'path/to/Category.csv' (DELIMITER ',', FORMAT CSV, ENCODING 'UTF8', HEADER);
COPY 3 #正常にインポート
次にProduct.csvをインポートをしようとするとエラーが出た。
practice_db=> \copy shop_product (name,slug,description,category,price,image,stock,available,created) FROM 'path/to/Product.csv' (DELIMITER ',', FORMAT CSV, ENCODING 'UTF8', HEADER);
ERROR:リレーション"shop_product"の列"category"は存在しません
解決方法
エラーが出た時にインポートしようとしたProduct.csvのcategoryのデータにはCategory.csvのnameの値が入っている。
これをnameの値で指定するのではなく、Categoryのidで指定しないとエラーが出てしまう。
さらに、カラム名をcategoryではなくcategory_idと変更する。
変更後のProduct.csvファイルは以下。
どうやら、ForeiginKey型のデータにはidが入る決まりらしい。
よく考えたら、Categoryのnameではなく、絶対に重複しないidで指定するべきだなと思った。