Comments (10)
Looked at the implementation - fetch_all_links
doesn't implement fetching BackLink
s. Maybe @roman-right accidently forgot it.
In this case the following happens:
Document.fetch_all_links
callsDocument.fetch_link
for each link- This branch in
Document.fetch_link
is executed, whereref_obj
is of typelist[BackLink]
Note thatif isinstance(ref_obj, list) and ref_obj: values = await Link.fetch_list(ref_obj, fetch_links=True) setattr(self, field, values)
Link.fetch_list
is called - it calls
Link.repack_links
to get linked documents that aren't fetched yet - which tries to get
id
from the link here and fails, becauseBackLink
doesn't haveid
So at the moment you have to use find
methods
from beanie.
Hi @sheoak , thank you for the issue. I'll check what is going on there and will update you here. It is probably a bug
from beanie.
I don't know if this is related, but in Pydantic v2 it seems like the way to define a BackLink
s original_field
is different from the description in the docs. From reading the source code the following seems to be the way to do it:
class Door(Document):
house: BackLink[House] = Field(json_schema_extra={"original_field": "door"})
as opposed to
class Door(Document):
house: BackLink[House] = Field(original_field="door")
from beanie.
I don't know if this is related, but in Pydantic v2 it seems like the way to define a
BackLink
soriginal_field
is different from the description in the docs
Yes, and the new format is poorly documented. But it still doesnβt work in my case.
from beanie.
Will this be resolved in the near future ?
Beside that it's a lot of try and error to get the magic behind it ... the documentation is kinda minimal when it comes to stuff like that. At the moment the whole code we use isn't even remotely populating something on the list of backlinked documents.
from beanie.
So at the moment you have to use
find
methods
I'm not quite sure if this is related, but when I try to find documents that have a BackLink I get an error, that the BackLink field can not be encoded
If you have any ideas how to work around this, please tell me π
Error
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/home/renja/projects/leaderboard/backend/app/test.py", line 52, in <module>
asyncio.run(init())
File "/home/renja/.pyenv/versions/3.12.2/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/home/renja/.pyenv/versions/3.12.2/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/.pyenv/versions/3.12.2/lib/python3.12/asyncio/base_events.py", line 685, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/app/test.py", line 45, in init
league_entries = await LeagueEntry.find(LeagueEntry.summoner == summoner).to_list()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/queries/cursor.py", line 72, in to_list
cursor = self.motor_cursor
^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/queries/find.py", line 688, in motor_cursor
filter=self.get_filter_query(),
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/queries/find.py", line 106, in get_filter_query
return Encoder(custom_encoders=self.encoders).encode(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/utils/encoder.py", line 134, in encode
return {str(key): self.encode(value) for key, value in obj.items()}
^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/utils/encoder.py", line 127, in encode
return self._encode_document(obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/utils/encoder.py", line 110, in _encode_document
obj_dict[key] = sub_encoder.encode(value)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/utils/encoder.py", line 136, in encode
return [self.encode(value) for value in obj]
^^^^^^^^^^^^^^^^^^
File "/home/renja/projects/leaderboard/backend/.venv/lib/python3.12/site-packages/beanie/odm/utils/encoder.py", line 138, in encode
raise ValueError(f"Cannot encode {obj!r}")
ValueError: Cannot encode <beanie.odm.fields.BackLink object at 0x7f6f5b7f7080>
Code
import asyncio
from beanie import init_beanie, Document
from motor.motor_asyncio import AsyncIOMotorClient
from app.models import Summoner, LeagueEntry
async def init():
client = AsyncIOMotorClient(
"mongodb://localhost:27017",
)
await init_beanie(database=client.test_db, document_models=[Summoner, LeagueEntry])
summoner = Summoner(
game_name = "test",
name = "test",
platform = "test",
profile_icon_id = 1,
puuid = "test",
summoner_id = "test",
summoner_level = 1,
tag_line = "test",
)
await summoner.insert()
league_entry = LeagueEntry(
league_id="test",
queue_type="test",
tier="test",
rank="test",
league_points=1,
wins=1,
losses=1,
veteran=False,
inactive=False,
fresh_blood=False,
hot_streak=False,
summoner=summoner,
)
await league_entry.insert()
# get all league entries of the summoner
league_entries = await LeagueEntry.find(LeagueEntry.summoner == summoner).to_list()
print(league_entries)
asyncio.run(init())
Models
import pymongo
from pydantic import BaseModel, Field
from beanie import Document, Link, BackLink
# A summoner can have multiple league entries or none at all
# A league entry is linked to a summoner
class Summoner(Document):
game_name: str
name: str
platform: str
profile_icon_id: int
puuid: str
summoner_id: str
summoner_level: int
tag_line: str
league_entries: list[BackLink["LeagueEntry"]] = Field(original_field="summoner")
class Settings:
name = "summoner"
indexes = [
[
("game_name", pymongo.TEXT),
("tag_line", pymongo.TEXT),
("platform", pymongo.TEXT),
]
]
class LeagueEntry(Document):
league_id: str
queue_type: str
tier: str
rank: str
league_points: int
wins: int
losses: int
veteran: bool
inactive: bool
fresh_blood: bool
hot_streak: bool
summoner: Link[Summoner]
class Settings:
name = "league_entry"
indexes = [
[
("tier", pymongo.TEXT),
("rank", pymongo.TEXT),
("league_points", pymongo.TEXT),
]
]
from beanie.
Any updates on this?
from beanie.
Any updates on this? Is there a way on demand fetch one particular BackLink field? Can someone share an example?
from beanie.
Yeah, this is causing issues for us as well, the weird part is that it seems to periodically work. Has any work been done on this?
from beanie.
it also seems that there are a lot of tickets on nested links not populating that have been closed by the bot even though they have not been completed. on the links we can run through the object and force them to populate, but because it isnt really possible to fetch a backlink after the initial search, this becomes quite difficult
from beanie.
Related Issues (20)
- [BUG] `original_field` is not supported by pydantic, makes typecheckers give a type error and causes a warning at runtime HOT 3
- [BUG] optional link type field in the form of union type expression (Link[A] | None bitwise or operation between link type and None) can not be recognized. HOT 2
- [BUG] Cannot change between parent class childrens HOT 3
- [BUG] save() results in OperationFailure if use_revision=True and keep_nulls=False HOT 1
- [BUG] wrong condition convertion on comparing two fields HOT 2
- [BUG] Inheritance doesn't work for backlinks? HOT 1
- [BUG] Exclude Parameter on Model Dump Does Not Work If Lazy Parsing With Embedded Pydantic Models HOT 1
- [BUG] Inheritance fails silently for uninitialized collections HOT 1
- [BUG] DeleteRules.DELETE_LINKS is not working? HOT 2
- [BUG] fetch_links error HOT 1
- [BUG] init_beanie takes more than 1.5 sec to initilaize the connection.
- [BUG] init_beanie working slow
- [BUG] skip_actions reset field's value to creation state
- [BUG]: Unable to serialize unknown type: <class 'beanie.odm.fields.BackLink'> HOT 3
- No support for Regex elements HOT 7
- [BUG] Backlinks cause errors when using documents as part of Pydantic union types
- [BUG] - Beanie migrations run throws no module named 'some_document'
- [BUG] Writerules.WRITE only works for first level fields
- [BUG] AttributeError while Trying to use operator without making init_beanie call
- [BUG] Logical operators are not type compliant when using bool operations
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from beanie.