I have troubles uploading a CSV file into my database, when I try to upload the file I get a "value too long for type character varying(25)" error message for the field performance_exccy
(see below for my django model). This error message started occuring when I switched from SQLite to PostgreSQL (using ElephantSQL), with SQLite the upload worked out perfectly.
The value causing the problem was 0.000000000000000000, which has 20 characters, but in my model I defined max_digit = 40
and dec_places =20
- so the number of digits should not be an issue.
What I also noticed is that the upload error did not start with the first row of the CSV file but with the 12th row, with the rows before having values of similar lenght.
My model:
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
My view:
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)