How to resolve sqlalchemy.orm.exc.UnmappedInstanceError

Refresh

November 2018

Views

36 time

2

I'm using Python Sqlalchemy for MYSQL db. I wrote the following script to create the class object and then add a row in the table.

from sqlalchemy import create_engine, MetaData, Table, Column, ForeignKey
from sqlalchemy.dialects.mysql.base import VARCHAR, LONGTEXT, INTEGER
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine("mysql+mysqldb://root:@localhost/mydb")
connection = engine.connect()

Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
metadata = MetaData()

class User(Base):
    __tablename__ = 'User'
    __abstract__ = True
    id = Column('id', INTEGER(display_width=11), primary_key=True, nullable=False)
    email = Column('email', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100), unique=True)
    password = Column('password', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=45))
    name = Column('name', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100))

Base.metadata.create_all(engine)

add_user = User(email = "[email protected]",
            password = 'testing',
            name = 'testing')
session.add(add_user)
session.commit()

When I try to add to session, it throws the following errors:

 AttributeError: 'User' object has no attribute '_sa_instance_state'

 During handling of the above exception, another exception occurred:

 raise exc.UnmappedInstanceError(instance)
 sqlalchemy.orm.exc.UnmappedInstanceError: Class '__main__.User' is not mapped

I'm new to SQLalchemy as well as OOP so can't figure out what I'm doing wrong here. Any help would be appreciated

1 answers

2

Проблема связана с определения __abstract__ == Trueна User.

Из документации :

__abstract__приводит к декларативным пропустить производство таблицы или картографа для класса полностью. Класс может быть добавлен в иерархии таким же образом, как подмешать (см подмешать и пользовательские базовые классы), что позволяет подклассам расширить только из специального класса

Если вы сделаете Userабстрактным, чтобы получить карту, он должен быть подклассами другой модели, например , это работает:

class User(Base):
    __tablename__ = 'User'
    __abstract__ = True
    id = Column('id', INTEGER(display_width=11), primary_key=True, nullable=False)
    email = Column('email', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100), unique=True)
    password = Column('password', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=45))
    name = Column('name', VARCHAR(charset='utf8mb4', collation='utf8mb4_0900_ai_ci', length=100))

class AUser(User):
    pass

if __name__ == '__main__':
    Base.metadata.create_all(bind=engine)

    add_user = AUser(email = "[email protected]",
                password = 'testing',
                name = 'testing')
    session.add(add_user)
    session.commit()