【问题标题】:pyDatalog: 'object is incompatible with the class queried' when asking a querypyDatalog:询问查询时“对象与查询的类不兼容”
【发布时间】:2013-08-27 13:56:57
【问题描述】:

我正在开发一个使用 pyDatalog 查询 sqlite 数据库的程序。数据库中的key表是Event,定义如下:

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)

然后每个事件都引用一个包含更多信息的详细信息表。

我希望能够对序列中的每个事件运行一系列查询。使用 pyDatalog.load() 从外部文件加载规则集

我遇到问题的部分是将每个事件 ID 的引用从 python 传递到数据日志中。我不断收到错误“TypeError:对象与查询的类不兼容。”

我已将规则缩减为以下这些以进行调试:

+ 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)

询问查询的代码如下所示(较大类的一部分):

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)

如果我取消注释 "query='parent(bill,X)'" 行,它可以正常工作(它打印 (bill, 'John Adams') 元组),但是使用 "query = 'getEvent(.. ." 行,它会在上面显示的最后一行出现上述错误。

有谁知道这个错误是什么意思,以及如何正确地将事件ID的引用传递给pyDatalog?

【问题讨论】:

  • Base 是否继承了 pyDatatlog 功能,使用 Base = declarative_base(cls=pyDatalog.Mixin, metaclass=pyDatalog.sqlMetaMixin) ?
  • 另外,你使用的是哪个版本的pyDatalog?
  • 我正在使用 pyDatalog 0.13.0。基类如上创建。但是我忘记将会话与基类相关联(见下文)。

标签: python logic-programming datalog


【解决方案1】:

pyDatalog 解析前缀谓词时会产生此错误,例如(Event.id[Evt] == EvtId) :表示Evt不是Event的实例,也不是pyDatalog变量。

因此,我可以想象您在这个内联 pyDatalog 语句中遇到错误。

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

我无法解释您将如何在这一行得到错误(使用 pyDatalog 0.13):

print pyDatalog.ask(query)

【讨论】:

    【解决方案2】:

    我通过重新阅读文档设法解决了这个问题。在基类中添加了 pyDatalog 功能,使用

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

    您还需要将会话与基类关联,其中:

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

    解决了这个问题,上面的例子就可以正常工作了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多