groc-prog / pyneo4j-ogm

A asynchronous Object-Graph-Mapper for Neo4j 5+ and Python 3.10+
MIT License
12 stars 1 forks source link

Multihop ModelInstance.find_connected_nodes raises TypeError when "*" explicitly passed to "$maxHops" param #2

Closed Zlyden-1 closed 7 months ago

Zlyden-1 commented 7 months ago

Subject of the issue

When passing "*" explicitly as in snippet below, the following error is raised by pydantic: TypeError: '>=' not supported between instances of 'str' and 'int'

It can be easily prevented by not passing the "*" and it will work correct, but in docs is mentined the possibility to do like this, so i decided to create an issue. I have ideas how to fix that, so i'll try in a few days and if i succeed i'll open a PR.

My environment

Steps to reproduce

Simple snippet to reproduce my issue:

import uuid

from pyneo4j_ogm import (
    Pyneo4jClient,
    NodeModel,
    RelationshipProperty,
    RelationshipPropertyCardinality,
    RelationshipPropertyDirection,
    RelationshipModel,
)

class Default(RelationshipModel):
    class Settings:
        type = "DEFAULT"

class Resource(NodeModel):
    ...

class Company(NodeModel):
    resources: RelationshipProperty["Resource", Default] = RelationshipProperty(
        target_model=Resource,
        relationship_model=Default,
        direction=RelationshipPropertyDirection.OUTGOING,
        cardinality=RelationshipPropertyCardinality.ZERO_OR_MORE,
        allow_multiple=False,
    )

class User(NodeModel):
    companies: RelationshipProperty["Company", Default] = RelationshipProperty(
        target_model="Company",
        relationship_model=Default,
        direction=RelationshipPropertyDirection.OUTGOING,
        cardinality=RelationshipPropertyCardinality.ZERO_OR_MORE,
        allow_multiple=False,
    )

async def main():
    client = Pyneo4jClient()
    await client.connect(
        uri="neo4j://localhost:7687", auth=("neo4j", "password"), database="neo4j"
    )
    await client.register_models([Default, Resource, Company, User])
    user = User()
    await user.create()
    resource = Resource()
    await resource.create()
    company = Company()
    await company.create()
    await user.companies.connect(company)
    await company.resources.connect(resource)
    reachable_resources = await user.find_connected_nodes(  # here TypeError is raised
        {
            "$maxHops": "*",
            "$node": {
                "$labels": resource._settings.labels,
            },
        }
    )
    client.close()
    print(reachable_resources)

if __name__ == "__main__":
    import asyncio

    asyncio.run(main())

Expected behaviour

Output like below: [Resource(element_id=4:0db21407-e480-4da7-9c4b-c9ddf43d9694:4, destroyed=False)]

Actual behaviour

TypeError: '>=' not supported between instances of 'str' and 'int'

groc-prog commented 7 months ago

Hey, seems like this issue is caused by how pydantic field options changed from v1 to v2. I will probaly be able to add a fix in the next few days if you don't beat me to it.