Skip to content

Commit 3ce3faf

Browse files
authored
2.0.0: Some initial support for deleting models and unpin libs (#67)
* slightly better for now * WIP * update travil.yml * precise * update version and add tests for deleted models * fixed and added test coverage * update to 2.0.0
1 parent 834fa1b commit 3ce3faf

File tree

10 files changed

+95
-40
lines changed

10 files changed

+95
-40
lines changed

.travis.yml

+8-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
sudo: false
22
language: python
3-
python: 3.5
3+
python: 3.6
44
cache: pip
5+
dist: precise
56
services:
67
- mysql
78
- postgresql
@@ -21,23 +22,15 @@ env:
2122
- TOX_ENV=py27-dj19
2223
- TOX_ENV=py27-dj110
2324
- TOX_ENV=py27-dj111
24-
- TOX_ENV=py27-djdev
25-
- TOX_ENV=py34-dj18
26-
- TOX_ENV=py34-dj19
27-
- TOX_ENV=py34-dj110
28-
- TOX_ENV=py34-dj111
29-
- TOX_ENV=py34-djdev
30-
- TOX_ENV=py35-dj18
31-
- TOX_ENV=py35-dj19
32-
- TOX_ENV=py35-dj110
33-
- TOX_ENV=py35-dj111
34-
- TOX_ENV=py35-djdev
25+
- TOX_ENV=py36-dj18
26+
- TOX_ENV=py36-dj19
27+
- TOX_ENV=py36-dj110
28+
- TOX_ENV=py36-dj111
29+
- TOX_ENV=py36-djdev
3530
matrix:
3631
fast_finish: true
3732
allow_failures:
38-
- env: TOX_ENV=py27-djdev
39-
- env: TOX_ENV=py34-djdev
40-
- env: TOX_ENV=py35-djdev
33+
- env: TOX_ENV=py36-djdev
4134

4235
before_install:
4336
- psql -c 'CREATE DATABASE "default";' -U postgres

CHANGES.md

+12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
Changelog
22
=========
33

4+
2.0.0 (Sep 10th 2017)
5+
6+
### Small updates
7+
8+
- Unpin `dj-database-url` from a specific minor version to a specific major version.
9+
- Initial support for deleting django models. I'm not going to update the docs just yet
10+
as I don't entirely like this solution...something is better than nothing.
11+
Check the `test_deleted_model_in_settings` tests to see this. The issue is that django
12+
needs to know about a model after you've deleted the class so sharded settings on deleted
13+
models need to be tracked somewhere.
14+
15+
416
1.2.0 (May 1st 2017)
517
------------------
618

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
include *.md
22
include requirements.txt
3+
include requirements/*.txt

django_sharding_library/router.py

+19-6
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,25 @@ def allow_migrate(self, db, app_label, model_name=None, **hints):
143143
# is the app label of the app where the change is defined but to app with the model is
144144
# passed in with the model name.
145145
try:
146-
app = apps.get_app_config(app_label)
147-
model = app.get_model(model_name)
148-
except LookupError:
149-
app_label = model_name.split('.')[0]
150-
app = apps.get_app_config(app_label)
151-
model = app.get_model(model_name[len(app_label) + 1:])
146+
if "." in model_name:
147+
_app_label = model_name.split('.')[0]
148+
app = apps.get_app_config(_app_label)
149+
model = app.get_model(model_name[len(_app_label) + 1:])
150+
else:
151+
app = apps.get_app_config(app_label)
152+
model = app.get_model(model_name)
153+
except LookupError as exception:
154+
deleted_model_settings = getattr(settings, 'DJANGO_SHARDING_SETTINGS', {}).get('DELETED_MODELS', {})
155+
entry = "{}.{}".format(app_label, model_name) if "." not in model_name else model_name
156+
if entry not in deleted_model_settings:
157+
raise exception
158+
deleted_model_data = deleted_model_settings[entry]
159+
if deleted_model_data is None or ("shard_group" not in deleted_model_data and "database" not in deleted_model_data):
160+
return db == "default"
161+
elif "database" in deleted_model_data:
162+
return db == deleted_model_data["database"]
163+
else:
164+
return settings.DATABASES[db]['SHARD_GROUP'] == deleted_model_data["shard_group"]
152165

153166
try:
154167
return is_model_class_on_database(model=model, database=db)

requirements/_without_django.txt

-1
This file was deleted.

requirements/common.txt

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
django>=1.8
2-
-r _without_django.txt
1+
dj-database-url>=0.4.1,<1.0.0

requirements/development.txt

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
psycopg2==2.6.2
2-
mock==2.0.0
3-
django_nose==1.4.4
4-
mysqlclient==1.3.7
5-
dj-database-url==0.4.1
1+
psycopg2>=2.6.2
2+
mock>=2.0.0
3+
django_nose>=1.4.4
4+
mysqlclient>=1.3.7

setup.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
from setuptools import setup, find_packages
22

3-
version = '1.2.0'
3+
version = '2.0.0'
4+
5+
6+
def get_requirements(file_path):
7+
with open(file_path) as f:
8+
return [line for line in f if line and not line.startswith('-')]
49

510

611
setup(
@@ -13,8 +18,8 @@
1318
url='https://github.com/JBKahn/django-sharding',
1419
packages=find_packages(),
1520
include_package_data=True,
16-
install_requires=['Django>=1.8', 'dj-database-url==0.4.1'],
17-
tests_require=['psycopg2==2.6.2', 'mysqlclient==1.3.7', 'mock==2.0.0', 'django_nose==1.4.4', 'tox==2.3.1'],
21+
install_requires=get_requirements('requirements/common.txt') + ["django>=1.8,<2.0.0"],
22+
tests_require=get_requirements('requirements/development.txt'),
1823
license="BSD",
1924
zip_safe=False,
2025
keywords='django shard sharding library',
@@ -24,7 +29,8 @@
2429
'Natural Language :: English',
2530
'Programming Language :: Python :: 2.7',
2631
'Programming Language :: Python :: 3.4',
27-
'Programming Language :: Python :: 3.5'
32+
'Programming Language :: Python :: 3.5',
33+
'Programming Language :: Python :: 3.6'
2834
],
2935
test_suite='runtests.run_tests',
3036
)

tests/test_router.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from django.conf import settings
55
from django.contrib.auth import get_user_model
66
from django.contrib.auth.models import Group
7-
from django.test import TransactionTestCase
7+
from django.test import TransactionTestCase, override_settings
88

99
from tests.models import TestModel, ShardedTestModelIDs, PostgresCustomAutoIDModel, PostgresShardUser
1010
from django_sharding_library.exceptions import InvalidMigrationException
@@ -524,6 +524,42 @@ def test_lookup_fallback_if_migration_directory_not_the_same_as_the_model(self):
524524
can_migrate_shard=False,
525525
)
526526

527+
@override_settings(DJANGO_SHARDING_SETTINGS={"DELETED_MODELS": {"deleted.Whatever": {"database": "app_shard_002"}}})
528+
def test_deleted_model_in_settings__specific_database(self):
529+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='default', app_label='deleted', **{}))
530+
self.assertTrue(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_002', app_label='deleted', **{}))
531+
532+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='default', app_label='deleted', **{}))
533+
self.assertTrue(self.sut.allow_migrate(model_name="Whatever", db='app_shard_002', app_label='deleted', **{}))
534+
535+
@override_settings(DJANGO_SHARDING_SETTINGS={"DELETED_MODELS": {"deleted.Whatever": {"shard_group": "default"}}})
536+
def test_deleted_model_in_settings__shard_group(self):
537+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='default', app_label='deleted', **{}))
538+
self.assertTrue(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001', app_label='deleted', **{}))
539+
self.assertTrue(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_002', app_label='deleted', **{}))
540+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001_replica_001', app_label='deleted', **{}))
541+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001_replica_002', app_label='deleted', **{}))
542+
543+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='default', app_label='deleted', **{}))
544+
self.assertTrue(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001', app_label='deleted', **{}))
545+
self.assertTrue(self.sut.allow_migrate(model_name="Whatever", db='app_shard_002', app_label='deleted', **{}))
546+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001_replica_001', app_label='deleted', **{}))
547+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001_replica_002', app_label='deleted', **{}))
548+
549+
@override_settings(DJANGO_SHARDING_SETTINGS={"DELETED_MODELS": {"deleted.Whatever": None}})
550+
def test_deleted_model_in_settings__unsharded(self):
551+
self.assertTrue(self.sut.allow_migrate(model_name="deleted.Whatever", db='default', app_label='deleted', **{}))
552+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001', app_label='deleted', **{}))
553+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_002', app_label='deleted', **{}))
554+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001_replica_001', app_label='deleted', **{}))
555+
self.assertFalse(self.sut.allow_migrate(model_name="deleted.Whatever", db='app_shard_001_replica_002', app_label='deleted', **{}))
556+
557+
self.assertTrue(self.sut.allow_migrate(model_name="Whatever", db='default', app_label='deleted', **{}))
558+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001', app_label='deleted', **{}))
559+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_002', app_label='deleted', **{}))
560+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001_replica_001', app_label='deleted', **{}))
561+
self.assertFalse(self.sut.allow_migrate(model_name="Whatever", db='app_shard_001_replica_002', app_label='deleted', **{}))
562+
527563

528564
class RouterForPostgresIDFieldTest(TransactionTestCase):
529565

tox.ini

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
[tox]
22
envlist =
33
py27-dj{18,19,110,111,dev}
4-
py34-dj{18,19,110,111,dev}
5-
py35-dj{18,19,110,111,dev}
4+
py36-dj{18,19,110,111,dev}
65

76
[testenv]
87
passenv=
@@ -16,12 +15,10 @@ passenv=
1615
TRAVIS
1716
basepython =
1817
py27: python2.7
19-
py34: python3.4
20-
py35: python3.5
18+
py36: python3.6
2119
deps =
2220
coverage
23-
-r{toxinidir}/requirements/_without_django.txt
24-
-r{toxinidir}/requirements/development.txt
21+
-r{toxinidir}/requirements.txt
2522
dj18: Django>=1.8,<1.9
2623
dj19: Django>=1.9,<1.10
2724
dj110: Django>=1.10,<1.11

0 commit comments

Comments
 (0)