Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EE-123 error exchange adapters failed to update exchange rate #5

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a53a380
Updated to minimal working state with python 3
jpclark6 Sep 17, 2019
7c727a8
Deleted migrations to update from south
jpclark6 Sep 17, 2019
7fd5ef3
Adds migration file using django instead of south
jpclark6 Sep 17, 2019
4d554ee
update importlib import, fix syntax error in except
Nov 6, 2019
e0960ef
Merge pull request #5 from GetAmbassador/python3_upgrade_importlib_im…
carpenter-js-zz Nov 6, 2019
cc7be6a
change importlib import
Nov 6, 2019
9f1f9ba
Updates currency to 19 decimal places to avoid error
jpclark6 Nov 7, 2019
ec41e36
Adds migration to increase max_length of currency amount
jpclark6 Nov 7, 2019
7f1b09f
Merge pull request #6 from GetAmbassador/3778-13-upgrade-ambassador-a…
jpclark6 Nov 7, 2019
b1a14a3
removed depricated code, transactions autocommitted in newer django
jpclark6 Nov 7, 2019
b3cb52f
Merge pull request #7 from GetAmbassador/transaction_fix
jpclark6 Nov 7, 2019
298e838
add on_delete to model foreign keys for django 2 update
Jan 6, 2020
b155bb9
remove typo
Jan 6, 2020
7b41f67
adding new migration
jpclark6 Jan 22, 2020
d89e69e
Merge pull request #8 from GetAmbassador/4227-upgrade-to-django-20
carpenter-js-zz Jan 30, 2020
d07127a
Handle KeyError exception when a Currecy code does not exists in the …
Jan 21, 2022
7b70170
Fixed exception message
Jan 25, 2022
665c518
Merge pull request #9 from GetAmbassador/ENG-85_Exchange_Rates_Over_1…
ggallohernandez Feb 1, 2022
f568a1b
Added Currency.active field
Feb 22, 2022
b65e5c7
Added missing migrations
Feb 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 26 additions & 19 deletions exchange/adapters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,34 @@ def update(self):

updates = []
inserts = []
currencies = list(Currency.objects.all())
currencies = list(Currency.objects.filter(active=True))
for source in currencies:
for target in currencies:
rate = self._get_rate_through_usd(source.code,
target.code,
usd_exchange_rates)

exchange_rate = ExchangeRate(source=source,
target=target,
rate=rate)

if (source.code, target.code) in existing:
exchange_rate.id = existing[(source.code, target.code)]
updates.append(exchange_rate)
logger.debug('exchange rate updated %s/%s=%s'
% (source, target, rate))
else:
inserts.append(exchange_rate)
logger.debug('exchange rate created %s/%s=%s'
% (source, target, rate))

try:
rate = self._get_rate_through_usd(source.code,
target.code,
usd_exchange_rates)

exchange_rate = ExchangeRate(source=source,
target=target,
rate=rate)

if (source.code, target.code) in existing:
exchange_rate.id = existing[(source.code, target.code)]
updates.append(exchange_rate)
logger.debug('exchange rate updated %s/%s=%s'
% (source, target, rate))
else:
inserts.append(exchange_rate)
logger.debug('exchange rate created %s/%s=%s'
% (source, target, rate))
except KeyError as e:
logger.exception('Failed to update exchange rate %s/%s.' % (source.code, target.code))
continue
except Exception as e:
logger.exception(e)
continue

logger.info('exchange rates updated for %s' % source.code)
logger.info("Updating %s rows" % len(updates))
update_many(updates)
Expand Down
2 changes: 1 addition & 1 deletion exchange/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.contrib import admin
from models import Currency, ExchangeRate
from .models import Currency, ExchangeRate

admin.site.register(Currency)
admin.site.register(ExchangeRate)
10 changes: 7 additions & 3 deletions exchange/cache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.core.cache import get_cache
from django.core.cache import cache
from django.conf import settings

from exchange.models import ExchangeRate
Expand All @@ -20,8 +20,12 @@

CACHE_TIMEOUT = 0 # Not configurable at all

cache = get_cache(CACHE_DATABASE)

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': CACHE_DATABASE,
}
}

def _get_cache_key(source_currency, target_currency):
return ':'.join([CACHE_KEY_PREFIX, source_currency, target_currency])
Expand Down
92 changes: 40 additions & 52 deletions exchange/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,41 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'Currency'
db.create_table(u'exchange_currency', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=3)),
('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
))
db.send_create_signal(u'exchange', ['Currency'])

# Adding model 'ExchangeRate'
db.create_table(u'exchange_exchangerate', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('source', self.gf('django.db.models.fields.related.ForeignKey')(related_name='rates', to=orm['exchange.Currency'])),
('target', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['exchange.Currency'])),
('rate', self.gf('django.db.models.fields.DecimalField')(max_digits=12, decimal_places=2)),
))
db.send_create_signal(u'exchange', ['ExchangeRate'])


def backwards(self, orm):
# Deleting model 'Currency'
db.delete_table(u'exchange_currency')

# Deleting model 'ExchangeRate'
db.delete_table(u'exchange_exchangerate')


models = {
u'exchange.currency': {
'Meta': {'object_name': 'Currency'},
'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '64'})
},
u'exchange.exchangerate': {
'Meta': {'object_name': 'ExchangeRate'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'rate': ('django.db.models.fields.DecimalField', [], {'max_digits': '12', 'decimal_places': '2'}),
'source': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rates'", 'to': u"orm['exchange.Currency']"}),
'target': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['exchange.Currency']"})
}
}

complete_apps = ['exchange']
# Generated by Django 1.11.20 on 2019-09-17 17:05
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Currency',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False)),
('code', models.CharField(max_length=3, unique=True)),
('name', models.CharField(max_length=64)),
],
options={
'verbose_name_plural': 'currencies',
},
),
migrations.CreateModel(
name='ExchangeRate',
fields=[
('id', models.AutoField(auto_created=True,
primary_key=True, serialize=False)),
('rate', models.DecimalField(decimal_places=8, max_digits=17)),
('source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
related_name='rates', to='exchange.Currency')),
('target', models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to='exchange.Currency')),
],
),
]
20 changes: 20 additions & 0 deletions exchange/migrations/0002_auto_20191107_1532.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-11-07 15:32
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('exchange', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='exchangerate',
name='rate',
field=models.DecimalField(decimal_places=8, max_digits=19),
),
]
36 changes: 0 additions & 36 deletions exchange/migrations/0002_auto__chg_field_exchangerate_rate.py

This file was deleted.

26 changes: 26 additions & 0 deletions exchange/migrations/0003_auto_20200122_2156.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 2.2 on 2020-01-22 21:56

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('exchange', '0002_auto_20191107_1532'),
]

operations = [
migrations.AlterField(
model_name='exchangerate',
name='source',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE,
related_name='rates', to='exchange.Currency'),
),
migrations.AlterField(
model_name='exchangerate',
name='target',
field=models.ForeignKey(
null=True, on_delete=django.db.models.deletion.CASCADE, to='exchange.Currency'),
),
]
18 changes: 18 additions & 0 deletions exchange/migrations/0004_currency_active.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2022-02-23 22:11

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('exchange', '0003_auto_20200122_2156'),
]

operations = [
migrations.AddField(
model_name='currency',
name='active',
field=models.BooleanField(default=True),
),
]
24 changes: 24 additions & 0 deletions exchange/migrations/0005_auto_20220224_2220.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.2.24 on 2022-02-24 22:20

from django.db import migrations

def commit_old_currencies_deactivation(apps, schema_editor):
Currency = apps.get_model("exchange", "Currency")
db_alias = schema_editor.connection.alias
Currency.objects.using(db_alias).filter(code__in=["MRO", "VEF"]).update(active=False)


def rollback_old_currencies_deactivation(apps, schema_editor):
Currency = apps.get_model("exchange", "Currency")
db_alias = schema_editor.connection.alias
Currency.objects.using(db_alias).filter(code__in=["MRO", "VEF"]).update(active=True)

class Migration(migrations.Migration):

dependencies = [
('exchange', '0004_currency_active'),
]

operations = [
migrations.RunPython(commit_old_currencies_deactivation, rollback_old_currencies_deactivation),
]
7 changes: 4 additions & 3 deletions exchange/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Currency(models.Model):
"""Model holds a currency information for a nationality"""
code = models.CharField(max_length=3, unique=True)
name = models.CharField(max_length=64)
active = models.BooleanField(default=True, help_text='Denotes whether or not the currency its being used and should update the exchange rates.')

class Meta:
verbose_name_plural = 'currencies'
Expand All @@ -20,9 +21,9 @@ def get_numeric_code(self):

class ExchangeRate(models.Model):
"""Model to persist exchange rates between currencies"""
source = models.ForeignKey('exchange.Currency', related_name='rates')
target = models.ForeignKey('exchange.Currency')
rate = models.DecimalField(max_digits=17, decimal_places=8)
source = models.ForeignKey('exchange.Currency', related_name='rates', null=True, on_delete=models.CASCADE)
target = models.ForeignKey('exchange.Currency', null=True, on_delete=models.CASCADE)
rate = models.DecimalField(max_digits=19, decimal_places=8)

objects = ExchangeRateManager()

Expand Down
8 changes: 3 additions & 5 deletions exchange/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def import_class(class_path):
'OrderedDict'
"""
try:
from django.utils.importlib import import_module
from importlib import import_module
module_name = '.'.join(class_path.split(".")[:-1])
mod = import_module(module_name)
return getattr(mod, class_path.split(".")[-1])
except Exception, detail:
except Exception as detail:
raise ImportError(detail)


Expand Down Expand Up @@ -54,7 +54,6 @@ def insert_many(objects, using="default"):
placeholders = ",".join(("%s",) * len(fields))
con.cursor().executemany("insert into %s (%s) values (%s)"
% (table, column_names, placeholders), parameters)
transaction.commit_unless_managed(using=using)


def update_many(objects, fields=[], using="default"):
Expand Down Expand Up @@ -86,7 +85,7 @@ def update_many(objects, fields=[], using="default"):
parameters = []
for o in objects:
parameters.append(tuple(f.get_db_prep_save(f.pre_save(o, True),
connection=con) for f in fields_with_pk))
connection=con) for f in fields_with_pk))

table = meta.db_table
assignments = ",".join(("%s=%%s" % con.ops.quote_name(f.column))
Expand All @@ -95,7 +94,6 @@ def update_many(objects, fields=[], using="default"):
% (table, assignments,
con.ops.quote_name(meta.pk.column)),
parameters)
transaction.commit_unless_managed(using=using)


def memoize(ttl=None):
Expand Down