Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'module' object has no attribute 'Person' #420

Closed
fredthedead opened this issue Mar 5, 2019 · 7 comments
Closed

'module' object has no attribute 'Person' #420

fredthedead opened this issue Mar 5, 2019 · 7 comments
Labels
marked_for_imminent_closure Fully or partially obsolete issue. Request clarification, close if none provided.

Comments

@fredthedead
Copy link
Contributor

fredthedead commented Mar 5, 2019

I'm trying the basic example from the docs and it's failing on this command germany = Country(code='DE').save() returning 'module' object has no attribute 'Person'

This is either an issue with the docs (which after re-reading them I still can't figure what's wrong) or with the package...

What's wrong?

(btw the Person/Jim node is create successfully...)

@aanastasiou
Copy link
Collaborator

Thank you, will have a quick look at this but in the meantime, would it be possible to post the exact snippet you are working on?

@aanastasiou
Copy link
Collaborator

Hello again. Two things about this:

  1. I cannot see any functional problem with that part of the code. What I tested was creating a Country, a Person and connecting the two. It would be worth elaborating If you are coming across this error after a specific sequence of operations (?).

  2. As a more general tip however, I would avoid this kind of reciprocal connectivity with RelationshipTo, RelationshipFrom. This is a short and simple example to demonstrate the neomodel functionality but if you want to establish a relationship and it is supposed to be traversable in both directions, then establish a Relationship and then provide a hint about the direction it should be traversed in a query via CYPHER.

Hope this helps.

@fredthedead
Copy link
Contributor Author

Many thanks for the quick reply

I switched to Relationship in both classes and getting the same error. Given that it works for you I guess it is something in my setup (I'm using the Neo4j 3.5.3 community docker image via ngrok, and tried two versions of Neomodel: 3.2.9 & 3.3.1

The full snippet is:

from neomodel import (config, StructuredNode, StringProperty, IntegerProperty,
    UniqueIdProperty, RelationshipTo, RelationshipFrom, Relationship)

config.DATABASE_URL = 'bolt://:@host:port'

class Country(StructuredNode):
    code = StringProperty(unique_index=True, required=True)
    inhabitant = Relationship('Person', 'IS_FROM')

class Person(StructuredNode):
    uid = UniqueIdProperty()
    name = StringProperty(unique_index=True)
    age = IntegerProperty(index=True, default=0)
    country = Relationship(Country, 'IS_FROM')

jim = Person(name='Jim', age=3).save()

germany = Country(code='DE').save() <--- the line that fails and returns the error

@aanastasiou
Copy link
Collaborator

@fredthedead No worries.

The point about the relationship note from above is about discouraging reciprocal relationships. The way this is modelled (in the revised version) establishes one undirected relationship from Country to Person and another from Person to Country. So, not much of an improvement I am afraid.

To an extent, what you are describing here could be part of an improvement in the way neomodel manages relationships at a higher level.

But, on where we are now:

  1. Try to establish just one Relationship of type IS_FROM. At the moment, the relationship will appear as an attribute on the neomodel entity it is defined in only.

  2. This simply means that you would not be able to perform From traversals from the "other" entity using the high level neomodel facilities for querying (node sets, etc). You might find this cumbersome depending on what you are trying to do, but it is still doable using neomodel with some reasonable adjustments.

  3. Establishing just one Relationship at the model level still means that the IS_FROM relationship will be established in the database as expected (one undirected relationship between two nodes) which means that you would still be able to traverse it via a node's cypher or neomodel.db's cypher_query.

  4. A node's query and neomodel.db.cypher_query functions can return properly instantiated objects, so from the point of view of READ operations, this is not a huge limitation.

  5. I will try replicating that error locally but I am not sure how quickly I will be able to do that. Are there any additional logs from neo4j or the full exception trace that might be revealing a bit more information about what is wrong?

Hope this helps.

@fredthedead
Copy link
Contributor Author

Thanks again, removing the relationship from one of the classes works and the two nodes get linked. As you've guessed, the reason I wanted to have the relationship in both entities is for the ease of querying. I'll try to achieve that using cypher as you suggested.

Here's the full exception trace, apologies for not including it earlier:

AttributeError                            Traceback (most recent call last)
<command-25674> in <module>()
----> 1 germany = Country(code='DE').save()

/local_disk0/pythonVirtualEnvDirs/virtualEnv/local/lib/python2.7/site-packages/neomodel/core.pyc in __init__(self, *args, **kwargs)
    204 
    205         for key, val in self.__all_relationships__:
--> 206             self.__dict__[key] = val.build_manager(self, key)
    207 
    208         super(StructuredNode, self).__init__(*args, **kwargs)

/local_disk0/pythonVirtualEnvDirs/virtualEnv/local/lib/python2.7/site-packages/neomodel/relationship_manager.pyc in build_manager(self, source, name)
    400 
    401     def build_manager(self, source, name):
--> 402         self._lookup_node_class()
    403         return self.manager(source, name, self.definition)
    404 

/local_disk0/pythonVirtualEnvDirs/virtualEnv/local/lib/python2.7/site-packages/neomodel/relationship_manager.pyc in _lookup_node_class(self)
    397                 else:
    398                     module = import_module(namespace).__name__
--> 399             self.definition['node_class'] = getattr(sys.modules[module], name)
    400 
    401     def build_manager(self, source, name):

AttributeError: 'module' object has no attribute 'Person'

I'm not able to inspect any of these values further since it's running in a notebook environment that doesn't support that.

@fredthedead
Copy link
Contributor Author

I dug deeper into this, I suspect this is something related to the code being ran in a notebook... it looks like the node classes belong to the __main__ module (that's what I get when I run inspect.getmodule(Person) -> <module '__main__' from '/local_disk0/tmp/PythonShell.py'>) but they are not listed when calling sys.modules[module_name]

@aanastasiou
Copy link
Collaborator

aanastasiou commented Mar 5, 2019

@fredthedead No worries.

This trace indicates a problem during the .save() operation itself indeed.

In my setup, I tried a Jupyter notebook and:

  1. Could not connect to a Python3 kernel

    • Switched to a Python 2 based notebook
  2. Tried to create a simple StructuredNode and use it to write to the database

    • Crashed the neo4j server

But finally got 2 working by stepping through the cells manually, making sure I leave a bit of time between evaluations.

Not really sure if this is something to do with the way the cells are evaluated internally by Jupyter, but perhaps the order of execution does matter here.

Can you please try running the cells one by one and manually (to ensure that the series of operations is preserved) and let me know if that worked for you?

@aanastasiou aanastasiou added the marked_for_imminent_closure Fully or partially obsolete issue. Request clarification, close if none provided. label Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
marked_for_imminent_closure Fully or partially obsolete issue. Request clarification, close if none provided.
Projects
None yet
Development

No branches or pull requests

2 participants