uralbash
uralbash

Reputation: 3598

SQLAlchemy 0.7 MapperEvent error

I have model

class CreatedMixin(object):

    __abstract__ = True

    @declared_attr
    def created_by(cls):
        return Column(Integer, ForeignKey('user.user_id',
                      onupdate="cascade", ondelete="restrict"))

    @declared_attr
    def updated_by(cls):
        return Column(Integer, ForeignKey('user.user_id',
                      onupdate="cascade", ondelete="restrict"))

    created_at = Column(DateTime, nullable=False, default=dt.now())
    updated_at = Column(DateTime, nullable=False, default=dt.now(),
                        onupdate=dt.now())


class Net(Base, CreatedMixin):
    """Net or subnet."""

    cidr = Column(postgresql.CIDR, index = True)
    description = Column(UnicodeText())

    parent_id = Column(Integer, ForeignKey('net.id'))
    parent = relationship("Net", remote_side="Net.id")

   def __init__(self, cidr=''):
       self.cidr = cidr

   def __repr__(self):
       return "%s" % self.cidr

To autofill fields created_by and update_by I use sqlalchemy.orm.events.MapperEvents (SQLAlchemy 0.7) like this:

def created_before_insert_listener(mapper, connection, target):
    # execute a stored procedure upon INSERT,
    # apply the value to the row to be inserted
    #target.calculated_value = connection.scalar(
    #                            "select my_special_function(%d)" 
    #                            % target.special_number)
    target.updated_by = 1

# associate the listener function with CreatedMixin,
# to execute during the "before_insert" hook
event.listen(CreatedMixin, 'before_insert', created_before_insert_listener)

But after run app, got the following error but is not mapped

sqlalchemy.orm.exc.UnmappedClassError: Class 'myapp.model.Net' 

What's wrong?

Upvotes: 1

Views: 659

Answers (1)

uralbash
uralbash

Reputation: 3598

The problem was quite simple, I use an Mixin in my models and inadvertently added to the basic model of property __abstract__ = True

Example:

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session

engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base(bind=engine)
Session = scoped_session(sessionmaker(engine))

class Mix(object):
    __abstract__ = True
    id =  Column(Integer, autoincrement=True, primary_key=True)

class User(Base, Mix):
    __tablename__ = 'users'

    name = Column(String)
    fullname = Column(String)
    password = Column(String)

Base.metadata.create_all()

u = User()
print u

But in SQLAlchemy 0.6 it works fine. Perhaps this is a bug of 0.6. Update: for more information SQLAlchemy abstract

Upvotes: 1

Related Questions