我正在尝试更改列名。第一次尝试是使用以下脚本:
meta = MetaData()
users = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50), unique=True),
Column('email', String(120), unique=True)
)
def upgrade(migrate_engine):
meta.bind = migrate_engine
users.c.id.alter(name='id')
def downgrade(migrate_engine):
meta.bind = migrate_engine
users.c.id.alter(name='user_id')在我的开发数据库(sqlite)上运行migrate.py test是可行的,升级和降级也是如此。但是,当我在Heroku (使用PostgreSQL 8.3 )上将其部署到我的测试环境中时,我在尝试升级时得到一个跟踪。要点是这样的信息:
sqlalchemy.exc.ProgrammingError: (ProgrammingError) column "id" does not exist 然后,我尝试在upgrade方法中使用users.c.user_id。这在两种环境中都失败了。
AttributeError: user_id我现在使用的解决方法是这个脚本:
meta_old = MetaData()
meta_new = MetaData()
users_old = Table('users', meta_old,
Column('user_id', Integer, primary_key=True),
Column('name', String(50), unique=True),
Column('email', String(120), unique=True)
)
users_new = Table('users', meta_new,
Column('id', Integer, primary_key=True),
Column('name', String(50), unique=True),
Column('email', String(120), unique=True)
)
def upgrade(migrate_engine):
meta_old.bind = migrate_engine
users_old.c.user_id.alter(name='id')
def downgrade(migrate_engine):
meta_new.bind = migrate_engine
users_new.c.id.alter(name='user_id')已经推荐的做法是将模型复制粘贴到sqlalchemy-migrate脚本。但是这些额外的重复对我来说有点太多了。任何人都知道应该如何做。假设这是一个bug,我想要一些关于如何解决这个问题的建议。
发布于 2011-10-06 18:10:12
事实证明,有一个比我所希望的更干燥的解决方案。自省!如下所示:
def upgrade(migrate_engine):
meta = MetaData(bind=migrate_engine)
users = Table('users', meta, autoload=True)
users.c.user_id.alter(name='id')
def downgrade(migrate_engine):
meta = MetaData(bind=migrate_engine)
users = Table('users', meta, autoload=True)
users.c.id.alter(name='user_id')就像一种护身符!
发布于 2017-09-28 00:08:06
这个也行得通:
from alembic import op
....
def upgrade(migrate_engine):
op.alter_column('users', 'user_id', new_column_name='id')
def downgrade(migrate_engine):
op.alter_column('users', 'id', new_column_name='user_id')发布于 2011-10-05 23:10:37
我敢打赌,它不能生成任何SQL,因为您的元数据引用混淆了。您似乎在Table类中使用了两个不同的元数据对象,这确实不太好。你只需要一个。元数据跟踪对象的陈旧情况,是否需要发出对象更新、外键约束等的查询,它还需要知道所有的表和关系。
更改为使用单个MetaData对象,并将echo=True传递给sqlalchemy.create_engine调用,它将把正在使用的SQL查询输出到标准输出。尝试以Postgres的相同角色(用户)登录时自己执行该查询。您可能会发现这是一个简单的权限问题。
关于复制粘贴:我认为Django有一个很好的约定,将Table和声明性类放在它们自己的模块中并导入它们。但是,因为您必须将MetaData对象传递给Table工厂,所以这会使问题复杂化。您可以使用单例/全局元数据对象,也可以直接转换为声明性对象。
有一段时间,我选择实现单参数函数,该函数在给定一个元数据的情况下返回Table对象并缓存结果--实际上实现了一个单例模型类。然后我觉得这很愚蠢,转而使用声明式。
https://stackoverflow.com/questions/7659957
复制相似问题