Package: arangodantic
ArangodanticDatabase models for ArangoDB using Pydantic base models.InstallationThe package is available on PyPI:pipinstallarangodantic# Or with Shylockpipinstallarangodantic[shylock]UsageDefine your database models by extending eitherDocumentModelorEdgeModel. Nested
structures can be created by extending pydantic.BaseModel.Configure Arangodantic. You can optionally define a collection name prefix, a key
generation function and a lock (needed if you want to use the locking functionality;Shylockis supported out of the box, any other
locking service such asSherlockshould at least
in theory also work).Ensure you have an ArangoDB server available with known credentialsdockerrun--rm-p8529:8529-eARANGO_ROOT_PASSWORD=""arangodb/arangodb:3.7.2.1importasynciofromuuidimportuuid4fromaioarangodbimportArangoClientfrompydanticimportBaseModelfromshylockimportAsyncLockasLockfromshylockimportShylockAioArangoDBBackendfromshylockimportconfigureasconfigure_shylockfromarangodanticimportASCENDING,DocumentModel,EdgeModel,configure# Define modelsclassOwner(BaseModel):"""Dummy owner Pydantic model."""first_name:strlast_name:strclassCompany(DocumentModel):"""Dummy company Arangodantic model."""company_id:strowner:OwnerclassLink(EdgeModel):"""Dummy Link Arangodantic model."""type:strasyncdefmain():# Configure the database settingshosts="http://localhost:8529"username="root"password=""database="example"prefix="example-"client=ArangoClient(hosts=hosts)# Connect to "_system" database and create the actual database if it doesn't exist# Only for demo, you likely want to create the database in advance.sys_db=awaitclient.db("_system",username=username,password=password)ifnotawaitsys_db.has_database(database):awaitsys_db.create_database(database)# Configure Arangodantic and Shylockdb=awaitclient.db(database,username=username,password=password)configure_shylock(awaitShylockAioArangoDBBackend.create(db,f"{prefix}shylock"))configure(db,prefix=prefix,key_gen=uuid4,lock=Lock)# Create collections if they don't yet exist# Only for demo, you likely want to create the collections in advance.awaitCompany.ensure_collection()awaitLink.ensure_collection()# Let's create some example entriesowner=Owner(first_name="John",last_name="Doe")company=Company(company_id="1234567-8",owner=owner)awaitcompany.save()print(f"Company saved with key:{company.key_}")second_owner=Owner(first_name="Jane",last_name="Doe")second_company=Company(company_id="2345678-9",owner=second_owner)awaitsecond_company.save()print(f"Second company saved with key:{second_company.key_}")link=Link(_from=company,_to=second_company,type="CustomerOf")awaitlink.save()print(f"Link saved with key:{link.key_}")# Hold named locks while loading and doing changesasyncwithCompany.lock_and_load(company.key_)asc:assertc.owner==ownerc.owner.first_name="Joanne"awaitc.save()awaitcompany.reload()print(f"Updated owner of company to '{company.owner!r}'")# Let's explore the find functionality# Note: You likely want to add indexes to support the queriesprint("Finding companies owned by a person with last name 'Doe'")asyncwith(awaitCompany.find({"owner.last_name":"Doe"},count=True))ascursor:print(f"Found{len(cursor)}companies")asyncforfound_companyincursor:print(f"Company:{found_company.company_id}")# Supported operators include: "==", "!=", "<", "<=", ">", ">="found_company=awaitCompany.find_one({"owner.last_name":"Doe","_id":{"!=":company}})print(f"Found the company{found_company.key_}")# Find also supports sorting and the cursor can easily be converted to a listcompanies=await(awaitCompany.find(sort=[("owner.last_name",ASCENDING),("owner.first_name",ASCENDING),])).to_list()print("Companies sorted by owner:")forcincompanies:print(f"Company{c.company_id}, owner:{c.owner!r}")if__name__=="__main__":# Starting from Python 3.7 -># asyncio.run(main())# Compatible with Python 3.6 ->loop=asyncio.get_event_loop()result=loop.run_until_complete(main())You might findmigrate-anythinguseful for creating and managing collections and indexes.More examplesThegraph exampleshows how arangodantic can be used with
graphs. Please note that graph related functionality is at the moment really limited
and will likely be extended later and might even be restructured, so use with caution.LicenseThis code is released under the BSD 3-Clause license. Details in theLICENSEfile.