How to avoid looping imports in Python Google App Engine Ndb (a pattern to avoid)

I am trying to find a pattern that eliminates circular imports in the Google App Engine Ndb Python datastore architecture. I want to have separate files which are parent mode and child models (parent related).

The only option I found was to attach the parent and children to the same file, but make the code too complex and not easy to scale (add multiple lines).

I currently have a project structure like this.

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

      

I've read this answer How to avoid circular imports in Python? and try to use but without success is OK with typical Python objects , but doesn't work with initialized ndb properties . I spend a few hours but have no idea why this is not working.

parent.py (needs 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 (requires parent for reference)

from google.appengine.ext import ndb
import parent

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

      

children.py (needs a base base too).

import base

class Child(base.BaseChild):
  pass

      

It throws an exception when I try to execute code like this 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'

      

+3


source to share


1 answer


You can replace the query that requires parent

to import children

, namely

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

      



with a query GQL

that is only satisfied with the lines:

ndb.gql('SELECT * FROM Child WHERE parent = :1').bind(self.key)

      

+1


source







All Articles