Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlalchemy + flask: class is not defined

i'm using sqlalchemy + alembic + Flask and i can't map circular classes.

apps/users/models.py:

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    email = Column(String)
    password = Column(String)
    session = relationship("Session", back_populates='user', cascade='all,delete', lazy='dynamic')

    notes = relationship('Note2User', back_populates='user', cascade='all,delete', lazy='dynamic')

apps/notes/models.py:

class Note2User(Base):
    __tablename__ = 'notes_users_m2m'

    id = Column(Integer, primary_key=True)

    user_id = Column(Integer, ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
    user = relationship('User', back_populates='notes')
    note_id = Column(Integer, ForeignKey('notes.id', ondelete='CASCADE'), nullable=False)
    note = relationship('Note', back_populates='users')

Table Note2User made for m2m relationship User <-> Notes, but when i start app and done some request, gets error:

InvalidRequestError: When initializing mapper Mapper|User|users, expression 'Note2User' failed to locate a name ("name 'Note2User' is not defined"). If this is a class name, consider adding this relationship() to the class after both dependent classes have been defined.

Initializing db in db/init.py: (dunder name)

from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session

engine = create_engine('postgresql+psycopg2://server:12345@localhost:5432/test')

Base = declarative_base()

meta = MetaData()
meta.reflect(bind=engine)

db_session = Session(bind=engine)
like image 732
Максим Стукало Avatar asked Dec 29 '25 05:12

Максим Стукало


2 Answers

Add an import for Note2User class in apps/users/models.py file so this model gets defined first before initializing that relatioship in User class which refrences it. like this

# file: apps/users/models.py
from ..notes.models import Note2User
like image 151
Zohaib Ijaz Avatar answered Dec 30 '25 21:12

Zohaib Ijaz


You need to import the user.models module into the notes.model module and vice versa. It would look something like this:

# file app/users/models.py
import app.notes.models as notes
# use it like this
notes.Notes2User()


# file app/notes/models.py
import app.users.models as users
users.User()

The advantage to this is that you will avoid circular dependency problems as your program inevitably grows. I had so many problems with circular dependencies when I was creating an app with your same stack. The only solution was to ditch the

from . import Foo

and only use

import bar.foo as foo

It is considered best practice to use the import syntax for this reason. Reference.

like image 36
Kyle Stuart Avatar answered Dec 30 '25 20:12

Kyle Stuart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!