0

I am working on building a role based auth system in Flask. I have followed the SQLAlchemy docs in setting up a many to many relationship as a user could have multiple roles and a role multiple users. Here are my models with the associated table:

class Role(db.Model):
    __tablename__ = "roles"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(30), unique=True)

    users = db.relationship("User", secondary=user_roles, backref="roles")

class User(UserMixin, db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    password_hash = db.Column(db.String(128))
    firstName = db.Column(db.String(64), index=True, unique=False)
    lastName = db.Column(db.String(64), index=True, unique=False)
    last_login = db.Column(db.DateTime, default=datetime.utcnow)

user_roles = db.Table(
    "user_roles",
    db.Model.metadata,
    db.Column("roles.id", db.ForeignKey("roles.id"), primary_key=True),
    db.Column("users.id", db.ForeignKey("users.id"), primary_key=True),
)

I did not include the methods as those don't seem to be causing the issue. I am getting the following Traceback when trying to add a user to the database.

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 4, in __init__
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/state.py", line 480, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/state.py", line 477, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/decl_base.py", line 1157, in _declarative_constructor
    setattr(self, k, kwargs[k])
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 459, in __set__
    self.impl.set(
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1602, in set
    collections.bulk_replace(
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 843, in bulk_replace
    appender(member, _sa_initiator=initiator)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 1169, in append
    item = __set(self, item, _sa_initiator)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 1134, in __set
    item = executor.fire_append_event(item, _sa_initiator)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 753, in fire_append_event
    return self.attr.fire_append_event(
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1429, in fire_append_event
    value = fn(state, value, initiator or self._append_token)
  File "/home/ryan/adstrat/adstrat-spec-claims/asc/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1765, in emit_backref_from_collection_append_event
    child_state, child_dict = instance_state(child), instance_dict(child)
AttributeError: 'str' object has no attribute '_sa_instance_state'

I have read through numerous questions about this but many are dealing with querying the database or failing on the commit step. I am failing on the db.session.add step. I have an empty database and this would be my first user so there should be no issues with unique tests failing.

Here's an example of what I am trying to do in the shell

u = User(username='Ryan', email='ryan@test.com', firstName='Ryan', lastName='Findley', roles=['Admin'])

Any thoughts?

Ryan
  • 97
  • 1
  • 12
  • 1
    `roles` need to be a sequence of `Role` instances. – Klaus D. Feb 25 '22 at 00:13
  • So I’ve seen things suggesting I need to query the database to see how the role looks in there. I tried setting a variable with the query of role = roles.query.filter_by(‘Admin’).first() but get an error that tiles is not defined. – Ryan Feb 25 '22 at 00:23

0 Answers0