pyDatalog: 'object is incompatible with the class queried' when asking a query

262 views Asked by At

I'm working on a program that uses pyDatalog to query an sqlite database. The key table in the database is Event, which is defined as follows:

class Event(Base):
  __tablename__ = 'Event'

  id = Column('id', Integer, primary_key = True)
  eventType = Column('eventType', Integer, ForeignKey('EventType.id'))
  dateTime = Column('dateTime', DateTime)

  def __init__(self, eventType, dateTime):
    self.eventType = eventType
    self.dateTime = dateTime

  def __repr__(self):
    return "<Event(%d, %d, %s)>" % (self.id, self.eventType, self.dateTime)

Each event then refers to a details table with more information.

What I want to be able to do is run a series of queries on each event in the sequence. The rulesets are loaded from an external file using pyDatalog.load()

The part I'm having trouble with is passing a reference to each event id into datalog from python. I keep getting the error "TypeError: Object is incompatible with the class that is queried."

I've reduced the rules down to these for debugging:

+ parent(bill, 'John Adams')
ancestor(X,Y) <= parent(X,Y)
ancestor(X,Y) <= parent(X,Z) & ancestor(Z,Y)

getEvent(EvtId, Evt) <= (Event.id[Evt] == EvtId)

The code that asks the query looks like this (part of a larger class):

def validateEvent(self, event):
  # validate the event instance 'event'
  print "validating event: %s" % (event)
  #query = 'parent(bill, X)'
  query = 'getEvent(' + str(event.id) + ', Evt)'
  print query
  print pyDatalog.ask(query)

If I uncomment the "query='parent(bill,X)'" line, it works OK (it prints the (bill, 'John Adams') tuple), but with the "query = 'getEvent(..." line, it keeps failing with the above error on the last line shown above.

Does anyone know what this error means, and how to pass the reference to the event id into pyDatalog correctly?

2

There are 2 answers

0
Pierre Carbonnelle On

This error is generated when pyDatalog parses prefixed predicates, e.g. (Event.id[Evt] == EvtId) : it means that Evt is not an instance of Event, nor a pyDatalog variable.

Thus, I could imagine that you get the error on this in-line pyDatalog statement.

getEvent(EvtId, Evt) <= (Event.id[Evt] == EvtId)

I cannot explain how you would get the error on this line (with pyDatalog 0.13):

print pyDatalog.ask(query)
0
highfellow On

I've managed to solve this by re-reading the documentation. Having added pyDatalog capabilities to the base class, using

Base = declarative_base(cls=pyDatalog.Mixin, metaclass=pyDatalog.sqlMetaMixin)

you also need to associate a session with the base class, with:

Session = sessionmaker(bind=engine)
session = Session()
Base.session = session

Having fixed this, the example above works correctly.