【问题标题】:sqlalchemy claims column has unique requirement when it does notsqlalchemy 声明列在没有的情况下具有独特的要求
【发布时间】:2017-10-26 15:10:39
【问题描述】:

我有以下型号

models.py

class Rules(db.Model):
    name=db.Column(db.String, primary_key=True)
    rule=db.Column(db.Integer, default='0', unique=False)

    def __repr__(self):  # pragma: no cover
        return '<Rules %r>' % (self.name)

如果我尝试在其中存储数据,它声称规则有一个独特的要求。我事件甚至明确声明 unique=False,但它仍然声称它必须是唯一的,并出现以下错误

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint        failed: rules.rule [SQL: u'INSERT INTO rules (name, rule) VALUES (?, ?)'] [parameters: ('dod_iaa_cyber', '2')]

我已多次运行以下脚本以尝试迁移它并修复错误无济于事。

db_migrate.py

#!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
v = api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
migration = SQLALCHEMY_MIGRATE_REPO + ('/versions/%03d_migration.py' % (v+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)
v = api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO)
print('New migration saved as ' + migration)
print('Current database version: ' + str(v))

007_migration.py,所有从003-007的迁移都和这个一样

from sqlalchemy import *
from migrate import *


from migrate.changeset import schema
pre_meta = MetaData()
post_meta = MetaData()

def upgrade(migrate_engine):
    # Upgrade operations go here. Don't create your own engine; bind
    # migrate_engine to your metadata
    pre_meta.bind = migrate_engine
    post_meta.bind = migrate_engine


def downgrade(migrate_engine):
    # Operations to reverse the above upgrade go here.
    pre_meta.bind = migrate_engine
    post_meta.bind = migrate_engine

002_migration.py,这个和其他的不同,主键是规则

from sqlalchemy import *
from migrate import *


from migrate.changeset import schema
pre_meta = MetaData()
post_meta = MetaData()
rules = Table('rules', post_meta,
    Column('rule', Integer, primary_key=True, nullable=False),
    Column('name', String(length=45)),
)


def upgrade(migrate_engine):
    # Upgrade operations go here. Don't create your own engine; bind
    # migrate_engine to your metadata
    pre_meta.bind = migrate_engine
    post_meta.bind = migrate_engine
    post_meta.tables['rules'].create()


def downgrade(migrate_engine):
    # Operations to reverse the above upgrade go here.
    pre_meta.bind = migrate_engine
    post_meta.bind = migrate_engine
    post_meta.tables['rules'].drop()

那么为什么新的迁移没有发现我将规则从主键更改为整数,我该如何正确转换它以备将来使用?

【问题讨论】:

  • 生成的迁移文件中有什么?
  • 好电话,迁移 002 已将规则作为主键,并且他们都没有更改它,因为以反映它不是主键的更改。关于如何强制它正确迁移的任何建议?

标签: python python-2.7 sqlalchemy flask-sqlalchemy


【解决方案1】:

你的名字是独一无二的吗?拥有主键意味着该字段是唯一的。

【讨论】:

  • 名称应该是唯一的,规则不应该是唯一的。当我尝试将条目添加到规则时,由于某种未知原因,它会强制它们是唯一的。
【解决方案2】:

修复方法是删除 models.py 中的表规则,然后迁移数据库,从而迫使它删除。之后,我重新添加了规则并再次迁移。这次它识别出 Rules.rule 不是唯一键并正确迁移。

感谢各位的帮助。我不确定为什么在迁移过程中我将规则更改为标准整数没有发现,但一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-24
    • 2017-04-24
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多