Python sqlalchemy:TypeError:Unhable类型创建实例,sqlalchemy

Python sqlalchemy:TypeError:Unhable类型创建实例,sqlalchemy,python,sqlalchemy,flask,flask-sqlalchemy,Python,Sqlalchemy,Flask,Flask Sqlalchemy,尝试更新以下内容的代码时出错: 从python 2.7到3.3 给出以下最基本的实例 test.py: from flask import Flask from flask.ext.sqlalchemy import SQLAlchemy from flask.ext.security import Security, UserMixin, RoleMixin, \ SQLAlchemyUserDatastore app = Flask(__name__) app.config['S

尝试更新以下内容的代码时出错: 从python 2.7到3.3

给出以下最基本的实例

test.py:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.security import Security, UserMixin, RoleMixin, \
     SQLAlchemyUserDatastore

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'

db = SQLAlchemy(app)
db.drop_all()

roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):
        id = db.Column(db.Integer(), primary_key=True)
        name = db.Column(db.String(80), unique=True)
        description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    last_login_at = db.Column(db.DateTime())
    current_login_at = db.Column(db.DateTime())
    last_login_ip = db.Column(db.String(100))
    current_login_ip = db.Column(db.String(100))
    login_count = db.Column(db.Integer)
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))


db.create_all()
app.security = Security(app, datastore=SQLAlchemyUserDatastore(db, User, Role))
ds = app.extensions['security'].datastore

def create_roles():
    for role in ('admin', 'editor', 'author'):
        ds.create_role(name=role)
    ds.commit()

create_roles()

def create_users(count=None):
    users = [('matt@lp.com', 'password', ['admin'], True),
             ('joe@lp.com', 'password', ['editor'], True),
             ('dave@lp.com', 'password', ['admin', 'editor'], True),
             ('jill@lp.com', 'password', ['author'], True),
             ('tiya@lp.com', 'password', [], False)]
    count = count or len(users)

    for u in users[:count]:
        pw = u[1]
        ds.create_user(email=u[0], password=pw,
                       roles=u[2], active=u[3])
    ds.commit()

create_users(1)
导致错误的原因:

Traceback (most recent call last):
File "test.py", line 62, in <module>
create_users(1)
File "test.py", line 59, in create_users
roles=u[2], active=u[3])
File "/media/lxch/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/current/public/flask-security/flask_security/datastore.py", line 164, in create_user
user = self.user_model(**self._prepare_create_user_args(**kwargs))
File "<string>", line 4, in __init__
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/orm/state.py", line 200, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/ext/declarative/base.py", line 425, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/orm/attributes.py", line 303, in __set__
instance_dict(instance), value, None)
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/orm/attributes.py", line 1001, in set
lambda adapter, i: adapter.adapt_like_to_iterable(i))
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/orm/attributes.py", line 1036, in _set_iterable
collections.bulk_replace(new_values, old_collection, new_collection)
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/orm/collections.py", line 803, in bulk_replace
constants = existing_idset.intersection(values or ())
File "/home/lxch/.virtualenvs/p3/lib/python3.3/site-packages/sqlalchemy/util/_collections.py", line 558, in intersection
result._members.update(self._working_set(members).intersection(other))
TypeError: unhashable type: 'Role'
回溯(最近一次呼叫最后一次):
文件“test.py”,第62行,在
创建用户(1)
文件“test.py”,第59行,在create_users中
角色=u[2],活动=u[3])
文件“/media/lxch/686e26f8-c6d4-4448-8fe4-c19802726dcb/projects/current/public/flask security/flask_security/datastore.py”,第164行,在create_user中
user=self.user\u model(**self.\u prepare\u create\u user\u args(**kwargs))
文件“”,第4行,在_init中__
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/orm/state.py”,第200行,在实例中
退货经理。原始初始(*混合[1:],**kwargs)
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/ext/declarative/base.py”,第425行,位于声明性构造函数中
setattr(self,k,kwargs[k])
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/orm/attributes.py”,第303行,在__
实例(实例,值,无)
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/orm/attributes.py”,第1001行,在集合中
lambda适配器,i:adapter.adapt_like_to_iterable(i))
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/orm/attributes.py”,第1036行,在可编辑的集合中
集合。批量替换(新集合值、旧集合、新集合)
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/orm/collections.py”,第803行,批量替换
常量=现有的_idset.intersection(值或())
文件“/home/lxch/.virtualenvs/p3/lib/python3.3/site packages/sqlalchemy/util/_collections.py”,第558行,位于交叉点
结果._成员.更新(自._工作_集合(成员).交叉点(其他))
TypeError:不可损坏的类型:“角色”
我正在努力理解为什么以及到底是什么:

TypeError:不可损坏的类型:“角色”


任何见解都值得赞赏。

这里讨论了类似的问题:

解决方案(或至少解决方法)是在角色类中定义一个散列函数,如下所示:

def __hash__(self):
    return hash(self.name)

这可能意味着使用
SQLAlchemyUserDatastore(db,User,Role)
create\u User()
的方式是错误的,因为我假设这个包想要将
Role
对象添加到集合中(并且
Role
对象可以散列)。似乎它试图将
角色
类本身添加到集合中。我刚刚又看了一遍--我会检查一下,这是我目前的知识库中没有考虑到的。我在该函数中做了一些奇怪的事情。我已经为该项目启动了一个py3分支,并更新了该函数以修复该问题: