Skip to content

Commit

Permalink
add ability to test all databases in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtepkeev committed May 1, 2017
1 parent 29e7e15 commit d91b350
Show file tree
Hide file tree
Showing 17 changed files with 851 additions and 918 deletions.
435 changes: 118 additions & 317 deletions .travis.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
0.5.6 (2017-05-XX)
++++++++++++++++++

- Added: Support for testing all databases in one go using ``DB=all`` environmental variable
- Fixed: Django: Unable to partition tables in multi database configuration without ``default`` database
- Fixed: PostgreSQL: Failed to partition a table if a reserved keyword was used as a column name (turned
out this wasn't fixed properly in v0.5.4) (thanks to `ra2er <https://github.com/ra2er>`__)
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Features
- `PostgreSQL <http://www.postgresql.org>`_ >= 8.0
- `MySQL <https://www.mysql.com>`_ >= 5.5

* Supports Python 2.6 - 3.5
* Supports Python 2.6 - 3.6
* Extensively documented

Dependencies
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Features
- `PostgreSQL <http://www.postgresql.org>`_ >= 8.0
- `MySQL <https://www.mysql.com>`_ >= 5.5

* Supports Python 2.6 - 3.5
* Supports Python 2.6 - 3.6
* Extensively documented

Dependencies
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def run_tests(self):
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
],
)
5 changes: 3 additions & 2 deletions tests/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ Alternatively, starting from v0.5.3 you can use
$ python setup.py test --orm=ORM --db=DB
where ORM is one of the supported ORMs (django, peewee, pony, sqlalchemy, sqlobject) and DB is one
of the supported databases (mysql, postgresql, sqlite). Using the above command will automatically
install all the dependencies needed for running tests, so you don't have to do it by hand.
of the supported databases (mysql, pgsql, sqlite) or "all" if you want to test all databases in
one go. Using the above command will automatically install all the dependencies needed for running
tests, so you don't have to do it by hand.
78 changes: 46 additions & 32 deletions tests/models/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,22 @@
databases = {
'sqlite': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'},
'pgsql': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'architect', 'USER': 'postgres'},
'postgresql': {'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'architect', 'USER': 'postgres'},
'mysql': {'ENGINE': 'django.db.backends.mysql', 'NAME': 'architect', 'USER': 'root'}
}

test_databases = databases.keys() if os.environ['DB'] == 'all' else [os.environ['DB']]
Router = type('Router', (object,), {
'allow_migrate': lambda self, db, *args, **hints: hints.get('model', args[0]).db == db, # Django 1.7 model args[0]
'allow_syncdb': lambda self, db, model: model.db == db, # Django <= 1.6
'db_for_read': lambda self, model, **hints: model.db,
'db_for_write': lambda self, model, **hints: model.db,
})

settings.configure(
MIDDLEWARE_CLASSES=(),
INSTALLED_APPS=('test',),
DATABASES={'default': databases[os.environ.get('DB')]}
DATABASE_ROUTERS=['{0}.Router'.format(__name__)],
DATABASES=dict(default={}, **databases),
)

# We don't have a real app with models, so we have to fake it
Expand All @@ -38,54 +46,60 @@
from django.core import management
from architect import install

# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
class Meta(object):
app_label = 'test'
db_table = 'test_rangedate{0}'.format(item)

name = 'RangeDate{0}'.format(item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')

locals()[name] = partition(type(name, (models.Model,), {
'__module__': 'test.models',
'name': models.CharField(max_length=255),
'created': models.DateTimeField(null=True),
'Meta': Meta,
}))

if os.environ.get('DB') in ('pgsql', 'postgresql'):
# Generation of entities for integer range partitioning
for item in ('2', '5'):
for database in test_databases:
dbname = database.capitalize()

# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
class Meta(object):
app_label = 'test'
db_table = 'test_rangeinteger{0}'.format(item)
db_table = 'test_rangedate{0}'.format(item)

name = 'RangeInteger{0}'.format(item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')
name = '{0}RangeDate{1}'.format(dbname, item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')

locals()[name] = partition(type(name, (models.Model,), {
'__module__': 'test.models',
'name': models.CharField(max_length=255),
'num': models.IntegerField(null=True),
'created': models.DateTimeField(null=True),
'Meta': Meta,
'db': database,
}))

# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
if database == 'pgsql':
# Generation of entities for integer range partitioning
for item in ('2', '5'):
class Meta(object):
app_label = 'test'
db_table = 'test_range{0}{1}'.format(subtype, item)
db_table = 'test_rangeinteger{0}'.format(item)

name = 'Range{0}{1}'.format(''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')
name = '{0}RangeInteger{1}'.format(dbname, item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')

locals()[name] = partition(type(name, (models.Model,), {
'__module__': 'test.models',
'name': models.CharField(max_length=255),
'title': models.CharField(max_length=255, null=True),
'num': models.IntegerField(null=True),
'Meta': Meta,
'db': database,
}))

management.call_command(command, run_syncdb=True, verbosity=0, interactive=False)
# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
for item in ('2', '5'):
class Meta(object):
app_label = 'test'
db_table = 'test_range{0}{1}'.format(subtype, item)

name = '{0}Range{1}{2}'.format(dbname, ''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')

locals()[name] = partition(type(name, (models.Model,), {
'__module__': 'test.models',
'name': models.CharField(max_length=255),
'title': models.CharField(max_length=255, null=True),
'Meta': Meta,
'db': database,
}))

management.call_command(command, database=database, run_syncdb=True, verbosity=0, interactive=False)
65 changes: 34 additions & 31 deletions tests/models/peewee.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,64 @@
databases = {
'sqlite': SqliteDatabase(':memory:'),
'pgsql': PostgresqlDatabase('architect', user='postgres'),
'postgresql': PostgresqlDatabase('architect', user='postgres'),
'mysql': MySQLDatabase('architect', user='root')
}

db = databases[os.environ.get('DB')]
test_databases = databases.keys() if os.environ['DB'] == 'all' else [os.environ['DB']]

# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
class Meta(object):
database = db
db_table = 'test_rangedate{0}'.format(item)
for database in test_databases:
dbname = database.capitalize()
db = databases[database]

name = 'RangeDate{0}'.format(item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')

locals()[name] = partition(type(name, (Model,), {
'name': CharField(),
'created': DateTimeField(null=True),
'Meta': Meta,
}))

locals()[name].create_table(True)

if os.environ.get('DB') in ('pgsql', 'postgresql'):
# Generation of entities for integer range partitioning
for item in ('2', '5'):
# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
class Meta(object):
database = db
db_table = 'test_rangeinteger{0}'.format(item)
db_table = 'test_rangedate{0}'.format(item)

name = 'RangeInteger{0}'.format(item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')
name = '{0}RangeDate{1}'.format(dbname, item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')

locals()[name] = partition(type(name, (Model,), {
'name': CharField(),
'num': IntegerField(null=True),
'created': DateTimeField(null=True),
'Meta': Meta,
}))

locals()[name].create_table(True)

# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
if database == 'pgsql':
# Generation of entities for integer range partitioning
for item in ('2', '5'):
class Meta(object):
database = db
db_table = 'test_range{0}{1}'.format(subtype, item)
db_table = 'test_rangeinteger{0}'.format(item)

name = 'Range{0}{1}'.format(''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')
name = '{0}RangeInteger{1}'.format(dbname, item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')

locals()[name] = partition(type(name, (Model,), {
'name': CharField(),
'title': CharField(null=True),
'num': IntegerField(null=True),
'Meta': Meta,
}))

locals()[name].create_table(True)

# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
for item in ('2', '5'):
class Meta(object):
database = db
db_table = 'test_range{0}{1}'.format(subtype, item)

name = '{0}Range{1}{2}'.format(dbname, ''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')

locals()[name] = partition(type(name, (Model,), {
'name': CharField(),
'title': CharField(null=True),
'Meta': Meta,
}))

locals()[name].create_table(True)
56 changes: 29 additions & 27 deletions tests/models/pony.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,48 @@
databases = {
'sqlite': {'type': 'sqlite', 'args': (':memory:',), 'kwargs': {}},
'pgsql': {'type': 'postgres', 'args': (), 'kwargs': {'user': 'postgres', 'database': 'architect'}},
'postgresql': {'type': 'postgres', 'args': (), 'kwargs': {'user': 'postgres', 'database': 'architect'}},
'mysql': {'type': 'mysql', 'args': (), 'kwargs': {'user': 'root', 'database': 'architect'}}
}

current = os.environ.get('DB')
db = Database(databases[current].pop('type'), *databases[current]['args'], **databases[current]['kwargs'])
test_databases = databases.keys() if os.environ['DB'] == 'all' else [os.environ['DB']]

# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
name = 'RangeDate{0}'.format(item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')
for database in test_databases:
dbname = database.capitalize()
db = Database(databases[database].pop('type'), *databases[database]['args'], **databases[database]['kwargs'])

locals()[name] = partition(type(name, (db.Entity,), {
'_table_': 'test_rangedate{0}'.format(item),
'name': Required(unicode),
'created': Optional(datetime.datetime, nullable=True),
}))

if os.environ.get('DB') in ('pgsql', 'postgresql'):
# Generation of entities for integer range partitioning
for item in ('2', '5'):
name = 'RangeInteger{0}'.format(item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')
# Generation of entities for date range partitioning
for item in ('day', 'week', 'month', 'year'):
name = '{0}RangeDate{1}'.format(dbname, item.capitalize())
partition = install('partition', type='range', subtype='date', constraint=item, column='created')

locals()[name] = partition(type(name, (db.Entity,), {
'_table_': 'test_rangeinteger{0}'.format(item),
'_table_': 'test_rangedate{0}'.format(item),
'name': Required(unicode),
'num': Optional(int, nullable=True)
'created': Optional(datetime.datetime, nullable=True),
}))

# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
if database == 'pgsql':
# Generation of entities for integer range partitioning
for item in ('2', '5'):
name = 'Range{0}{1}'.format(''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')
name = '{0}RangeInteger{1}'.format(dbname, item)
partition = install('partition', type='range', subtype='integer', constraint=item, column='num')

locals()[name] = partition(type(name, (db.Entity,), {
'_table_': 'test_range{0}{1}'.format(subtype, item),
'_table_': 'test_rangeinteger{0}'.format(item),
'name': Required(unicode),
'title': Optional(unicode, nullable=True),
'num': Optional(int, nullable=True)
}))

db.generate_mapping(create_tables=True)
# Generation of entities for string range partitioning
for subtype in ('string_firstchars', 'string_lastchars'):
for item in ('2', '5'):
name = '{0}Range{1}{2}'.format(dbname, ''.join(s.capitalize() for s in subtype.split('_')), item)
partition = install('partition', type='range', subtype=subtype, constraint=item, column='title')

locals()[name] = partition(type(name, (db.Entity,), {
'_table_': 'test_range{0}{1}'.format(subtype, item),
'name': Required(unicode),
'title': Optional(unicode, nullable=True),
}))

db.generate_mapping(create_tables=True)
Loading

0 comments on commit d91b350

Please sign in to comment.