# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/admin/migration.py
# def no_update_callable() -> update.MigrationUpdate:
#   def __init__(
#       self,
#       migration_id: str,
#       prev_migration_id: Optional[str],
#       upgrade: Optional[Callable[[], update.MigrationUpdate]] = None,
#       downgrade: Optional[Callable[[], update.MigrationUpdate]] = None,
#   ):
#   def migration_id(self) -> str:
#   def prev_migration_id(self) -> Optional[str]:
#   def upgrade(self) -> Optional[Callable[[], update.MigrationUpdate]]:
#   def downgrade(self) -> Optional[Callable[[], update.MigrationUpdate]]:
# class Migration:


import datetime
import importlib
import os
import re
import string
import uuid
from typing import Iterable, List, Optional
from spanner_orm import error
from spanner_orm.admin import migration
      result = migration.Migration(module.migration_id,
                                   module.prev_migration_id,
                                   getattr(module, 'upgrade', None),
                                   getattr(module, 'downgrade', None))
    except AttributeError:
      raise error.SpannerError('{} has no migration id'.format(path))
    return result

  def _all_migrations(self) -> List[migration.Migration]:
    """Loads all migrations from the base dir."""
    migrations = []
    for filename in os.listdir(self.basedir):
      _, ext = os.path.splitext(filename)
      if ext == '.py' and filename != '__init__.py':
        migrations.append(self._migration_from_file(filename))
    return migrations

  def _order_migrations(
      self,
      migrations: Iterable[migration.Migration]) -> List[migration.Migration]:
    """Returns list of migrations in the order they have to be applied."""
    if not migrations:
      return []

    id_map = {migration_.migration_id: migration_ for migration_ in migrations}
    start_migration = None
    for migration_id, migration_ in id_map.items():
      if migration_.prev_migration_id and migration_.prev_migration_id in id_map:
        current = id_map[migration_.prev_migration_id]
        if hasattr(current, 'next'):

# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/admin/migration.py
# def no_update_callable() -> update.MigrationUpdate:
#   def __init__(
#       self,
#       migration_id: str,
#       prev_migration_id: Optional[str],
#       upgrade: Optional[Callable[[], update.MigrationUpdate]] = None,
#       downgrade: Optional[Callable[[], update.MigrationUpdate]] = None,
#   ):
#   def migration_id(self) -> str:
#   def prev_migration_id(self) -> Optional[str]:
#   def upgrade(self) -> Optional[Callable[[], update.MigrationUpdate]]:
#   def downgrade(self) -> Optional[Callable[[], update.MigrationUpdate]]:
# class Migration:


# Path: spanner_orm/admin/migration_manager.py
import datetime
import importlib
import os
import re
import string
import uuid
from typing import Iterable, List, Optional
from spanner_orm import error
from spanner_orm.admin import migration

      result = migration.Migration(module.migration_id,
                                   module.prev_migration_id,
                                   getattr(module, 'upgrade', None),
                                   getattr(module, 'downgrade', None))
    except AttributeError:
      raise error.SpannerError('{} has no migration id'.format(path))
    return result

  def _all_migrations(self) -> List[migration.Migration]:
    """Loads all migrations from the base dir."""
    migrations = []
    for filename in os.listdir(self.basedir):
      _, ext = os.path.splitext(filename)
      if ext == '.py' and filename != '__init__.py':
        migrations.append(self._migration_from_file(filename))
    return migrations

  def _order_migrations(
      self,
      migrations: Iterable[migration.Migration]) -> List[migration.Migration]:
    """Returns list of migrations in the order they have to be applied."""
    if not migrations:
      return []

    id_map = {migration_.migration_id: migration_ for migration_ in migrations}
    start_migration = None
    for migration_id, migration_ in id_map.items():
      if migration_.prev_migration_id and migration_.prev_migration_id in id_map:
        current = id_map[migration_.prev_migration_id]
        if hasattr(current, 'next'):

          raise error.SpannerError(