Python / SQL Alchemy Migrate - 迁移db中的更改时,“ValueError:解压缩的值太多”

时间:2013-11-27 19:03:00

标签: python sqlalchemy migration flask

我在SQLAlchemy中编写了几个模型,我刚刚开始运行迁移脚本时遇到异常:ValueError:要解压的值太多

以下是我的模特:

from app import db

ROLE_USER = 0
ROLE_ADMIN = 1


class UserModel(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(25), index=True)
    password = db.Column(db.String(50))
    email = db.Column(db.String(50), index=True, unique=True)
    role = db.Column(db.SmallInteger, default=ROLE_USER)

    def __repr__(self):
        return '<User %r>' % (self.username)


class ConferenceModel(db.Model):
    __tablename__ = 'conference'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(40), index=True, unique=True)
    teams = db.relationship('TeamModel', backref='conference', lazy='dynamic')

    def __repr__(self):
        return '<Conference %r>' % (self.name)


class TeamModel(db.Model):
    __tablename__ = 'team'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), index=True, unique=True)
    conference_id = db.Column(db.Integer, db.ForeignKey('conference.id'))
    players = db.relationship('PlayerModel', backref='team', lazy='dynamic')

    def __repr__(self):
        return '<Team %r>' % (self.name)

class PlayerModel(db.Model):
    __tablename__ = 'player'
    id = db.Column(db.Integer, primary_key=True)
    season = db.Column(db.String(4), index=True)
    name = db.Column(db.String(75), index=True)
    number = db.Column(db.String(3))
    position = db.Column(db.String(4))
    height = db.Column(db.Integer)
    weight = db.Column(db.Integer)
    academic_class = db.Column(db.String(2))
    hometown = db.Column(db.String(40))
    status = db.Column(db.SmallInteger)
    team_id = db.Column(db.Integer, db.ForeignKey('team.id'))

    def __repr__(self):
        return '<player %r>' % (self.name)


class GameModel(db.Model):
    __tablename__ = 'game'

    id = db.Column(db.Integer, primary_key=True)
    espn_id = db.Column(db.Integer, index=True)
    date_time = db.Column(db.DateTime)
    location = db.Column(db.String(100))
    home_final = db.Column(db.Integer)
    away_final = db.Column(db.Integer)
    game_type = db.Column(db.Integer)
    season = db.Column(db.Integer)
    home_team_id = db.Column(db.Integer, db.ForeignKey('team.id'))
    away_team_id = db.Column(db.Integer, db.ForeignKey('team.id'))

    home_team = db.relationship("TeamModel", backref="homegames", foreign_keys=[home_team_id])
    away_team = db.relationship("TeamModel", backref="awaygames", foreign_keys=[away_team_id])


class ScoreDataModel(db.Model):
    __tablename__ = 'scoredata'

    id = db.Column(db.Integer, primary_key=True)
    starter = db.Column(db.Boolean)
    minutes_played = db.Column(db.Integer)
    field_goals_made = db.Column(db.Integer)
    field_goals_attempted = db.Column(db.Integer)
    three_pointers_made = db.Column(db.Integer)
    three_pointers_attempted = db.Column(db.Integer)
    free_throws_made = db.Column(db.Integer)
    free_throws_attempted = db.Column(db.Integer)
    offensive_rebounds = db.Column(db.Integer)
    rebounds = db.Column(db.Integer)
    assists = db.Column(db.Integer)
    steals = db.Column(db.Integer)
    blocks = db.Column(db.Integer)
    turnovers = db.Column(db.Integer)
    personal_fouls = db.Column(db.Integer)
    points = db.Column(db.Integer)


    # Added the columns below and the migrate script blew up...
    # I've taken them out and added other columns, but the error still presents
    player_id = db.Column(db.Integer, db.ForeignKey('player.id'))
    game_id = db.Column(db.Integer, db.ForeignKey('game.id'))

    player = db.relationship("PlayerModel", backref="boxscores")
    game = db.relationship("GameModel", backref="boxscore")

这是我的迁移脚本(这是由Miguel Grinberg的Mega Flask教程拍摄的):

#!flask/bin/python
import imp
from migrate.versioning import api
from app import db
from config import SQLALCHEMY_DATABASE_URI
from config import SQLALCHEMY_MIGRATE_REPO
migration = SQLALCHEMY_MIGRATE_REPO + '/versions/%03d_migration.py' % (api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) + 1)
tmp_module = imp.new_module('old_model')
old_model = api.create_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
exec old_model in tmp_module.__dict__
script = api.make_update_script_for_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, tmp_module.meta, db.metadata)
open(migration, "wt").write(script)
api.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
print 'New migration saved as ' + migration
print 'Current database version: ' + str(api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO))

这是追溯:

/Users/johncaine/anaconda/bin/python /Volumes/Spano/Dropbox/Dropbox/eclipse-workspace/CAUDLE/src/caudle/caudle/db_migrate.py
Traceback (most recent call last):
  File "/Volumes/Spano/Dropbox/Dropbox/eclipse-workspace/CAUDLE/src/caudle/caudle/db_migrate.py", line 11, in <module>
    script = api.make_update_script_for_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, tmp_module.meta, db.metadata)
  File "<string>", line 2, in make_update_script_for_model
  File "/Users/johncaine/anaconda/lib/python2.7/site-packages/migrate/versioning/util/__init__.py", line 89, in catch_known_errors
    return f(*a, **kw)
  File "<string>", line 2, in make_update_script_for_model
  File "/Users/johncaine/anaconda/lib/python2.7/site-packages/migrate/versioning/util/__init__.py", line 159, in with_engine
    return f(*a, **kw)
  File "/Users/johncaine/anaconda/lib/python2.7/site-packages/migrate/versioning/api.py", line 321, in make_update_script_for_model
    engine, oldmodel, model, repository, **opts)
  File "/Users/johncaine/anaconda/lib/python2.7/site-packages/migrate/versioning/script/py.py", line 69, in make_update_script_for_model
    genmodel.ModelGenerator(diff,engine).genB2AMigration()
  File "/Users/johncaine/anaconda/lib/python2.7/site-packages/migrate/versioning/genmodel.py", line 197, in genB2AMigration
    for modelCol, databaseCol, modelDecl, databaseDecl in td.columns_different:
ValueError: too many values to unpack

我相信我做的唯一改变就是在这个开始爆炸时添加ScoreDataModel。我似乎无法回到我可以解决的问题。

1 个答案:

答案 0 :(得分:13)

我遇到了与sqlalchemy + mysql相同的问题。 我在我的模型中有布尔字段,它们在mysql中使用smallint创建 在迁移脚本中,它将模型数据类型与模式数据类型(在我的情况下来自mysql)进行比较。 sqlalchemy默认将boolean数据类型转换为tinyint,而在mysql中,使用smallint创建模式。

迁移脚本在识别模型和架构之间的差异时抛出指定的错误。 我将模型数据类型从db.Boolean更改为db.SmallInteger以解决此问题。