3

I am trying find pattern avoiding circular import in Python Google App Engine Ndb datastore architecture. I want to have separate files which parent mode and children models (related to parent).

Only option which I found is to join parent and children into one file but it make code too complicated and not easy to scale (add more lines).

Currently I have such project structure.

parent.py - parent entity
base.py - abstract base entity for children
children.py - children module

I was read this answer How to avoid circular imports in Python? and trying to use but without success it is O.K. with typical Python objects but not works with initialized ndb properties. I spend some hours but has no idea why it is not works.

parent.py (need children for delete dependencies)

import children
from google.appengine.ext import ndb

class Parent(ndb.Model):
  def deleteWithChildren(self):
    for child in children.Child.query(Child.parent == self.key).fetch():
      child.key.delete()
    self.key.delete()

base.py (need parent for Reference)

from google.appengine.ext import ndb
import parent

class BaseChild(ndb.Model):
  parent = ndb.KeyProperty(kind=parent.Parent)

children.py (need base do need Parent too)

import base

class Child(base.BaseChild):
  pass

It produce exception when I try to execute such code import Parent:

  File "sandbox\sandbox.py", line 6, in <module>
    from web_site.seo.frontend.sandbox.parent import Parent
  File "sandbox\parent.py", line 4, in <module>
    import children
  File "sandbox\children.py", line 4, in <module>
    import base
  File "sandbox\base.py", line 7, in <module>
    class BaseChild(ndb.Model):
  File "sandbox\base.py", line 8, in BaseChild
    parent = ndb.KeyProperty(model=parent.Parent)
AttributeError: 'module' object has no attribute 'Parent'
Community
  • 1
  • 1
Chameleon
  • 9,722
  • 16
  • 65
  • 127

1 Answers1

2

You can replace the query requiring parent to import children, namely

children.Child.query(Child.parent == self.key)

with a GQL query, which is happy with just strings:

ndb.gql('SELECT * FROM Child WHERE parent = :1').bind(self.key)
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395