首页 > 解决方案 > sqlalchemy 多对多关系(重复键的值打破了唯一约束)flask_user 角色

问题描述

你能帮助我吗,

当我运行这个脚本时,它运行良好

class User(db.Model, UserMixin):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    active = db.Column('is_active', db.Boolean(), nullable=False, server_default='1')

    # User authentication information. The collation='NOCASE' is required
    # to search case insensitively when USER_IFIND_MODE is 'nocase_collation'.
    email = db.Column(db.String(255, collation='NOCASE'), nullable=False, unique=True)
    email_confirmed_at = db.Column(db.DateTime())
    password = db.Column(db.String(255), nullable=False, server_default='')

    # User information
    first_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')
    last_name = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='')

    # Define the relationship to Role via UserRoles
    roles = db.relationship('Role', secondary='user_roles')

# Define the Role data-model
class Role(db.Model):
    __tablename__ = 'roles'
    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(50), unique=True)

# Define the UserRoles association table
class UserRoles(db.Model):
    __tablename__ = 'user_roles'
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE'))
    role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE'))

# Setup Flask-User and specify the User data-model
user_manager = UserManager(app, db, User)

# Create all database tables
db.create_all()

# Create 'member@example.com' user with no roles
if not User.query.filter(User.email == 'member@example.com').first():
    user = User(
        email='member@example.com',
        email_confirmed_at=datetime.datetime.utcnow(),
        password=user_manager.hash_password('Password1'),
    )
    db.session.add(user)
    db.session.commit()

# Create 'admin@example.com' user with 'Admin' and 'Agent' roles
if not User.query.filter(User.email == 'admin@example.com').first():
    user = User(
        email='admin@example.com',
        email_confirmed_at=datetime.datetime.utcnow(),
        password=user_manager.hash_password('Password1'),
    )
    user.roles.append(Role(name='Admin'))
    user.roles.append(Role(name='Agent'))
    db.session.add(user)
    db.session.commit()

在这个阶段,代码工作没有问题,但问题是在我添加另一个用户之后,该用户的角色已经存在,在这种情况下,管理员角色或代理角色,例如,如果我在下面添加代码,则会显示错误消息

    if not User.query.filter(User.email == 'admin2@example.com').first():
    user = User(
        email='admin2@example.com',
        email_confirmed_at=datetime.datetime.utcnow(),
        password=user_manager.hash_password('Password1'),
    )
    user.roles.append(Role(name='Admin'))
    user.roles.append(Role(name='Agent'))
    db.session.add(user)
    db.session.commit()

sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) ERREUR: la valeur d'une clé dupliquée rompt la contrainte unique « roles_name_key » DETAIL: La clé « (name)=(Admin) » exists déjà。[SQL: 'INSERT INTO roles (name) VALUES (%(name)s) RETURNING roles.id'] [parameters: {'name': 'Admin'}] (此错误的背景:http://sqlalche。我/e/gkpj)

我尝试了不同的数据库驱动程序(pg8000、pygresql、py-postgresql),但仍然是同样的问题,

因为错误消息显示了问题,因为名称值是唯一的

name = db.Column (db.String (50), unique = True)

你能解释一下我犯了什么错误,这部分代码的作用是什么

# Define the relationship to Role via UserRoles

roles = db.relationship ('Role', secondary = 'user_roles')

我将烧瓶与 flask_user 一起使用

标签: postgresqlflasksqlalchemymany-to-manyflask-sqlalchemy

解决方案


推荐阅读