# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import six
+import pytest
+
+pytestmark = pytest.mark.skipif(six.PY3, reason='needs sqlalchemy.migrate')
+
import copy
from sqlalchemy import (
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.sql import select, insert
-from migrate import changeset
+if six.PY2:
+ from migrate import changeset
-from mediagoblin.db.sql.base import GMGTableBase
-from mediagoblin.db.sql.util import MigrationManager, RegisterMigration
+from mediagoblin.db.base import GMGTableBase
+from mediagoblin.db.migration_tools import MigrationManager, RegisterMigration
+from mediagoblin.tools.common import CollectingPrinter
# This one will get filled with local migrations
SET1_MODELS = [Creature1, Level1]
+FOUNDATIONS = {Creature1:[{'name':u'goblin','num_legs':2,'is_demon':False},
+ {'name':u'cerberus','num_legs':4,'is_demon':True}]
+ }
+
SET1_MIGRATIONS = {}
#######################################################
for level in result:
- for exit_name, to_level in level['exits'].iteritems():
+ for exit_name, to_level in six.iteritems(level['exits']):
# Insert the level exit
db_conn.execute(
level_exits.insert().values(
creature_power.c.hitpower.alter(type=Float)
+@RegisterMigration(8, FULL_MIGRATIONS)
+def creature_power_name_creature_unique(db_conn):
+ """
+ Add a unique constraint to name and creature on creature_power.
+
+ We don't want multiple creature powers with the same name per creature!
+ """
+ # Note: We don't actually check to see if this constraint is set
+ # up because at present there's no way to do so in sqlalchemy :\
+
+ metadata = MetaData(bind=db_conn.bind)
+
+ creature_power = Table(
+ 'creature_power', metadata,
+ autoload=True, autoload_with=db_conn.bind)
+
+ cons = changeset.constraint.UniqueConstraint(
+ 'name', 'creature', table=creature_power)
+
+ cons.create()
+
+
def _insert_migration1_objects(session):
"""
Test objects to insert for the first set of things
name=u'The Necroplex',
description=u'A complex full of pure deathzone.',
exits={
- 'deathwell': 'evilstorm',
- 'portal': 'central_park'}),
+ u'deathwell': u'evilstorm',
+ u'portal': u'central_park'}),
Level1(id=u'evilstorm',
name=u'Evil Storm',
description=u'A storm full of pure evil.',
name=u'Central Park, NY, NY',
description=u"New York's friendly Central Park.",
exits={
- 'portal': 'necroplex'})])
+ u'portal': u'necroplex'})])
session.commit()
session.commit()
-
-class CollectingPrinter(object):
- def __init__(self):
- self.collection = []
-
- def __call__(self, string):
- self.collection.append(string)
-
- @property
- def combined_string(self):
- return u''.join(self.collection)
-
-
def create_test_engine():
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=False)
printer = CollectingPrinter()
migration_manager = MigrationManager(
- '__main__', SET1_MODELS, SET1_MIGRATIONS, Session(),
+ u'__main__', SET1_MODELS, FOUNDATIONS, SET1_MIGRATIONS, Session(),
printer)
# Check latest migration and database current migration
assert result == u'inited'
# Check output
assert printer.combined_string == (
- "-> Initializing main mediagoblin tables... done.\n")
+ "-> Initializing main mediagoblin tables... done.\n" + \
+ " + Laying foundations for Creature1 table\n" )
# Check version in database
assert migration_manager.latest_migration == 0
assert migration_manager.database_current_migration == 0
+
# Install the initial set
# -----------------------
# Try to "re-migrate" with same manager settings... nothing should happen
migration_manager = MigrationManager(
- '__main__', SET1_MODELS, SET1_MIGRATIONS, Session(),
- printer)
+ u'__main__', SET1_MODELS, FOUNDATIONS, SET1_MIGRATIONS,
+ Session(), printer)
assert migration_manager.init_or_migrate() == None
# Check version in database
# Now check to see if stuff seems to be in there.
session = Session()
+ # Check the creation of the foundation rows on the creature table
+ creature = session.query(Creature1).filter_by(
+ name=u'goblin').one()
+ assert creature.num_legs == 2
+ assert creature.is_demon == False
+
+ creature = session.query(Creature1).filter_by(
+ name=u'cerberus').one()
+ assert creature.num_legs == 4
+ assert creature.is_demon == True
+
+
+ # Check the creation of the inserted rows on the creature and levels tables
+
creature = session.query(Creature1).filter_by(
name=u'centipede').one()
assert creature.num_legs == 100
# isn't said to be updated yet
printer = CollectingPrinter()
migration_manager = MigrationManager(
- '__main__', SET3_MODELS, SET3_MIGRATIONS, Session(),
+ u'__main__', SET3_MODELS, FOUNDATIONS, SET3_MIGRATIONS, Session(),
printer)
- assert migration_manager.latest_migration == 7
+ assert migration_manager.latest_migration == 8
assert migration_manager.database_current_migration == 0
# Migrate
+ Running migration 5, "level_exit_index_from_and_to_level"... done.
+ Running migration 6, "creature_power_index_creature"... done.
+ Running migration 7, "creature_power_hitpower_to_float"... done.
+ + Running migration 8, "creature_power_name_creature_unique"... done.
"""
# Make sure version matches expected
migration_manager = MigrationManager(
- '__main__', SET3_MODELS, SET3_MIGRATIONS, Session(),
+ u'__main__', SET3_MODELS, FOUNDATIONS, SET3_MIGRATIONS, Session(),
printer)
- assert migration_manager.latest_migration == 7
- assert migration_manager.database_current_migration == 7
+ assert migration_manager.latest_migration == 8
+ assert migration_manager.database_current_migration == 8
# Check all things in database match expected
# Now check to see if stuff seems to be in there.
session = Session()
+
+
+ # Start with making sure that the foundations did not run again
+ assert session.query(Creature3).filter_by(
+ name=u'goblin').count() == 1
+ assert session.query(Creature3).filter_by(
+ name=u'cerberus').count() == 1
+
+ # Then make sure the models have been migrated correctly
creature = session.query(Creature3).filter_by(
name=u'centipede').one()
assert creature.num_limbs == 100.0