У меня проблемы с загрузкой файла CSV в мою базу данных, когда я пытаюсь загрузить файл, я получаю сообщение об ошибке «значение, слишком длинное для изменяемого символа (25)» для поля performance_exccy
(см. Ниже мой djangoмодель). Это сообщение об ошибке начало появляться, когда я переключился с SQLite на PostgreSQL (используя ElephantSQL), с SQLite загрузка прошла отлично.
Значение, вызвавшее проблему, было 0,000000000000000000, которое имеет 20 символов, но в моей модели я определил max_digit = 40
и dec_places =20
- поэтому количество цифр не должно быть проблемой. Что я также заметил, так это то, что ошибка загрузки началась не с первой строки файла CSV, а с 12-й строки, строки которой имели значения одинаковой длины.
Моя модель:
class Testdata3(models.Model):
key = models.CharField(max_length=100, primary_key=True)
mnemonic = models.CharField(max_length=50)
assetclass = models.CharField(max_length=25)
value = models.DecimalField(max_digits=25,decimal_places=10)
performance = models.DecimalField(max_digits=40,decimal_places=20)
performance_exccy = models.DecimalField(max_digits=40,decimal_places=20)
performance_abs = models.DecimalField(max_digits=40,decimal_places=20)
performance_abs_exccy = models.DecimalField(max_digits=40,decimal_places=20)
date = models.DateField()
def __str__(self):
return self.key
Мой взгляд:
def file_upload(request):
template = "upload.html"
prompt = {
'order': 'Order of the CSV should be "placeholder_1", "placeholder_2", "placeholder_3" '
}
if request.method == "GET":
return render(request, template, prompt)
csv_file = request.FILES['file']
if not csv_file.name.endswith('.csv'):
messages.error(request, 'This is not a csv file')
data_set = csv_file.read().decode('UTF-8')
io_string = io.StringIO(data_set)
#Ignores header row by jumping to next row
next(io_string)
for column in csv.reader(io_string, delimiter=';', quotechar="|"):
# Check if csv-row is empty, if true jump to next iteration/row
if all(elem == "" for elem in column):
next
else:
_, created = Testdata3.objects.update_or_create(
key = column[0],
defaults = {
'key' : column[0],
# Get everything after the date part in the primary key
'mnemonic': re.findall(r'AMCS#[0-9]*(.*)', column[0])[0],
# Create datetime object from a string
'date' : datetime.datetime.strptime(column[6], '%d/%m/%Y'),
'assetclass' : column[10],
'value' : column[16],
'performance' : column[19],
'performance_abs' : column[20],
'performance_abs_exccy' : column[30],
'performance_exccy' : column[31],
}
)
context = {}
return render(request, template, context)