Gagan
Gagan

Reputation: 5654

Error importing a custom class from a module in the current location

I have a file called blogtag.py as follows

from .base import Base
from sqlalchemy import Column, Integer, String, schema, Sequence, Boolean
from sqlalchemy.orm import relationship
from .blogpost import Blogpost


class Tag(Base):
    """Tag model."""

    __tablename__ = 'tag'

    tag_id_seq = Sequence('tag_id_seq', metadata=Base.metadata)
    id = Column("id",Integer, tag_id_seq,server_default=tag_id_seq.next_value(), primary_key=True)
    name = Column('name', String)
    isactive = Column('isactive', Boolean)
    postList = relationship(Blogpost, secondary="posttag")

and another file in the same location , called blogpost.py which looks like this as follows

from .base import Base
import datetime
from sqlalchemy import Column, ForeignKey, Integer, String, Sequence, Boolean, Text, DateTime
from sqlalchemy.orm import relationship
from .image import Image
from .blogtag import Tag

class Blogpost(Base):
    """Post model."""

    __tablename__ = 'post'

    post_id_seq = Sequence('post_id_seq', metadata=Base.metadata)
    id = Column("id",Integer, post_id_seq,server_default=post_id_seq.next_value(), primary_key=True)
    title = Column('title', String)    
    imageList = relationship(Image, backref="post")
    tagList = relationship(Tag, secondary="posttag")

Now , everytime I try to run my setup.py which imports both the files, I keep getting this error

 File "blogtag.py", line 4, in <module>
    from .blogpost import Blogpost
ImportError: cannot import name 'Blogpost'

Can you please let me know what might be happening here please ?

Thanks

Upvotes: 1

Views: 147

Answers (1)

Umesh Chaudhary
Umesh Chaudhary

Reputation: 411

This is a case of circular import. In general, circular imports are the sign of bad design.

in module blogpost.py

from .blogtag import Tag

You are importing Tag class which forces the python interpreter to first load blogtag module.

Then in blogtag.py

from .blogpost import Blogpost

which again tells interpreter to load Blogpost class first. But interpreter already have been to the blogpost module and Blogpost class is yet not loaded into memory. So interpreter says that there is no class Blogpost in blogpost.py

To solve this issue, the best solution is to remove mapping statements and create a mapping model for Tag and Blogpost

module blogtag.py

from .base import Base
from sqlalchemy import Column, Integer, String, schema, Sequence, Boolean
from sqlalchemy.orm import relationship


class Tag(Base):
    """Tag model."""

    __tablename__ = 'tag'

    tag_id_seq = Sequence('tag_id_seq', metadata=Base.metadata)
    id = Column("id",Integer, tag_id_seq,server_default=tag_id_seq.next_value(), primary_key=True)
    name = Column('name', String)
    isactive = Column('isactive', Boolean)

module blogpost.py

from .base import Base
import datetime
from sqlalchemy import Column, ForeignKey, Integer, String, Sequence, Boolean, Text, DateTime
from sqlalchemy.orm import relationship
from .image import Image


class Blogpost(Base):
    """Post model."""

    __tablename__ = 'post'

    post_id_seq = Sequence('post_id_seq', metadata=Base.metadata)
    id = Column("id",Integer, post_id_seq,server_default=post_id_seq.next_value(), primary_key=True)
    title = Column('title', String)    
    imageList = relationship(Image, backref="post")

mapping module tag_blogpost_mapping.py

from sqlalchemy.orm import relationship

from .base import Base
from .blogtag import Tag
from .blogpost import Blogpost


class BlogpostTagMapping(Base):
    tag = relationship(Tag)
    blogpost = relationship(Blogpost)

Upvotes: 1

Related Questions