Python Forum

Full Version: Flask-SqlAlchemy - Relationship failed to locate a name - Please Help
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all,

I'm trying to connect to an existing sharepoint database (read only,) and
I'm getting the following error when I try to set up a many2many relationship between users and groups:

sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class 
SPT_group->Groups, expression 
'and_(SPT_group.site_id == SPT_group_member.c.SiteId, SPT_group.id == SPT_group_member.c.GroupId)' 
failed to locate a name ("name 'SPT_group_member' is not defined"). 
If this is a class name, consider adding this relationship() to the 
<class 'app.sharepoint.models.SPT_group'> class after both dependent classes have been defined.
I'm trying to follow this basic structure, but I have my models seperated out in directories as Blueprints.
https://blog.miguelgrinberg.com/post/the...-structure
We plan on using this as a "glue" app between lots of different systems, so the idea is to have all seperate blueprints. I'm pretty sure I don't understand how to properly deal with imports. Please Help.

I have tried putting the following in both app/__init__.py and app/sharepoint/__init__.py
"from app.sharepoint import models"
I have also tried putting this in both __init__.p files
"from app.sharepoint.models import SPT_group_member, SPT_user, SPT_group"
Nothing seems to work.

My Structure:
MyApp
|_app
  |___init__.py
  |_main
    |___init__.py
    |_routes.py
  |_sharepoint
    |___init__.py
    |_models.py
    |_routes.py
    |_forms.py
  |_security
    |___init__.py
    |_models.py
    |_routes.py
    |_forms.py
    ...
----
my app/__init__.py

from flask import Flask, request, current_app
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
...

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)
    db.init_app(app)
	...

    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    from app.sharepoint import bp as sharepoint_bp
    app.register_blueprint(sharepoint_bp, url_prefix='/sharepoint')
	
    from app.security import bp as security_bp
    app.register_blueprint(security_bp, url_prefix='/security')
	

    return app

----
my app/sharepoint/__init__.py

from flask import Blueprint
bp = Blueprint('sharepoint', __name__)
from app.sharepoint import models, routes, forms
----
my app/sharepoint/models.py

SPT_group_member = db.Table('GroupMembership', db.Model.metadata,
    db.Column('SiteId', db.String(128), db.ForeignKey('dbo.Groups.SiteId'), primary_key=True),
    db.Column('GroupId', db.Integer(), db.ForeignKey('dbo.Groups.ID'), primary_key=True),
    db.Column('MemberId', db.Integer(), db.ForeignKey('dbo.UserInfo.tp_ID'), primary_key=True),
    info={'bind_key': 'sharepoint', 'table_args': {'schema': 'dbo'}}
)


class SPT_user(db.Model): #db.Model.metadata
    __tablename__ = 'UserInfo'
    __table_args__ = {'schema': 'dbo'}
    __bind_key__ = 'sharepoint'

    site_id = db.Column('tp_SiteID', db.String(128),  primary_key=True)
    user_id = db.Column('tp_ID', db.Integer(), primary_key=True)

    tp_DomainGroup = db.Column(db.Boolean())
    tp_Deleted = db.Column(db.Integer())
    tp_SiteAdmin = db.Column(db.Boolean())
    tp_IsActive = db.Column(db.Boolean())
    tp_Login = db.Column(db.String(255))
    tp_Title = db.Column(db.String(255))
    tp_Email = db.Column(db.String(255))
    tp_Notes = db.Column(db.String(1023))
    tp_Locale = db.Column(db.Integer())
    tp_CalendarType = db.Column(db.Integer())
    tp_AdjustHijriDays = db.Column(db.Integer())
    tp_TimeZone = db.Column(db.Integer())
    tp_Time24 = db.Column(db.Boolean())
    tp_AltCalendarType = db.Column(db.Integer())
    tp_CalendarViewOptions = db.Column(db.Integer())
    tp_WorkDays = db.Column(db.Integer())
    tp_WorkDayStartHour = db.Column(db.Integer())
    tp_WorkDayEndHour = db.Column(db.Integer())
    tp_Mobile = db.Column(db.String(127))
    tp_Flags = db.Column(db.Integer())
    tp_ExternalTokenLastUpdated = db.Column(db.DateTime(timezone=True))

    def __repr__(self):
        return "<SPT_user(site_id='%s', user_id='%s')>" % (self.site_id, self.user_id)



class SPT_group(db.Model):
    __tablename__ = 'Groups'
    __table_args__ = {'schema': 'dbo'}
    __bind_key__ = 'sharepoint'
    
    site_id = db.Column('SiteId', db.String(128),  primary_key=True)
    id = db.Column('ID', db.String(128),  primary_key=True)

    members = db.relationship(SPT_user, secondary=SPT_group_member, 
                    primaryjoin="and_(SPT_group.site_id == SPT_group_member.c.SiteId, "
                    					"SPT_group.id == SPT_group_member.c.GroupId)",
                    secondaryjoin="and_(SPT_group_member.c.SiteId == SPT_user.site_id,"
                   					"SPT_group_member.c.MemberId == SPT_user.user_id)",
                    backref=db.backref('groups', lazy='dynamic'), 
                    lazy='dynamic'
    )

    title = db.Column(db.String(255))
    description = db.Column(db.String(512))
    owner = db.Column(db.Integer())
    ownerIsUser = db.Column(db.Boolean())
    dLAlias = db.Column(db.String(128))
    dLErrorMessage = db.Column(db.String(512))
    dLFlags = db.Column(db.Integer())
    dLJobId = db.Column(db.Integer())
    dLArchives = db.Column(db.VARCHAR)
    requestEmail = db.Column(db.String(255))
    flags = db.Column(db.Integer())

    def __repr__(self):
        return "<SPT_group(site_id='%s', id='%s')>" % (self.site_id, self.id)