@@ -50,3 +50,161 @@ and make your changes on a [new branch][about-branches].
5050[ pulls ] : https://github.com/linkml/linkml-store/pulls/
5151
5252We recommend also reading [ GitHub Pull Requests: 10 Tips to Know] ( https://blog.mergify.com/github-pull-requests-10-tips-to-know/ )
53+
54+ ## Adding a New Backend Store
55+
56+ LinkML-Store supports multiple backend stores (databases) through a common abstraction layer. To add support for a new backend, follow these steps:
57+
58+ ### 1. Create the Backend Module Structure
59+
60+ Create a new directory under ` src/linkml_store/api/stores/ ` for your backend:
61+
62+ ```
63+ src/linkml_store/api/stores/mybackend/
64+ __init__.py
65+ mybackend_database.py
66+ mybackend_collection.py
67+ ```
68+
69+ ### 2. Implement the Database Class
70+
71+ Create a database class that inherits from ` linkml_store.api.Database ` :
72+
73+ ``` python
74+ from linkml_store.api import Database
75+ from .mybackend_collection import MyBackendCollection
76+
77+ class MyBackendDatabase (Database ):
78+ collection_class = MyBackendCollection
79+
80+ def __init__ (self , handle : Optional[str ] = None , ** kwargs ):
81+ super ().__init__ (handle = handle, ** kwargs)
82+ # Initialize your backend connection here
83+
84+ def commit (self , ** kwargs ):
85+ # Implement transaction commit
86+ pass
87+
88+ def close (self , ** kwargs ):
89+ # Close backend connection
90+ pass
91+
92+ def drop (self , missing_ok = True , ** kwargs ):
93+ # Drop the database
94+ pass
95+
96+ def list_collection_names (self ) -> List[str ]:
97+ # Return list of collection names
98+ pass
99+ ```
100+
101+ ### 3. Implement the Collection Class
102+
103+ Create a collection class that inherits from ` linkml_store.api.Collection ` :
104+
105+ ``` python
106+ from linkml_store.api import Collection
107+ from linkml_store.api.queries import Query, QueryResult
108+
109+ class MyBackendCollection (Collection ):
110+ def insert (self , objs : Union[OBJECT , List[OBJECT ]], ** kwargs ):
111+ # Insert objects into the collection
112+ pass
113+
114+ def delete (self , objs : Union[OBJECT , List[OBJECT ]], ** kwargs ) -> Optional[int ]:
115+ # Delete objects from the collection
116+ pass
117+
118+ def query (self , query : Query, ** kwargs ) -> QueryResult:
119+ # Execute a query and return results
120+ pass
121+
122+ def find (self , where : Optional[Dict[str , Any]] = None , ** kwargs ) -> QueryResult:
123+ # Find objects matching criteria
124+ pass
125+
126+ def update (self , objs : Union[OBJECT , List[OBJECT ]], ** kwargs ):
127+ # Update existing objects
128+ pass
129+ ```
130+
131+ ### 4. Register the Backend
132+
133+ Add your backend to the ` HANDLE_MAP ` in ` src/linkml_store/api/client.py ` :
134+
135+ ``` python
136+ HANDLE_MAP = {
137+ # ... existing backends ...
138+ " mybackend" : " linkml_store.api.stores.mybackend.mybackend_database.MyBackendDatabase" ,
139+ }
140+ ```
141+
142+ If your backend uses file extensions, add them to ` SUFFIX_MAP ` :
143+
144+ ``` python
145+ SUFFIX_MAP = {
146+ # ... existing suffixes ...
147+ " mdb" : " mybackend:///{path} " ,
148+ }
149+ ```
150+
151+ ### 5. Add Dependencies
152+
153+ If your backend requires additional dependencies, add them to ` pyproject.toml ` :
154+
155+ ``` toml
156+ [tool .poetry .extras ]
157+ mybackend = [" mybackend-python-client>=1.0.0" ]
158+ all = [
159+ # ... existing dependencies ...
160+ " mybackend-python-client>=1.0.0" ,
161+ ]
162+ ```
163+
164+ ### 6. Write Tests
165+
166+ Create test files in the ` tests/ ` directory:
167+
168+ ``` python
169+ # tests/test_stores/test_mybackend.py
170+ import pytest
171+ from linkml_store import Client
172+
173+ def test_mybackend_basic_operations ():
174+ client = Client()
175+ db = client.attach_database(" mybackend:///:memory:" , alias = " test" )
176+ collection = db.create_collection(" TestCollection" )
177+
178+ # Test insert
179+ collection.insert([{" id" : " 1" , " name" : " Test" }])
180+
181+ # Test query
182+ result = collection.find()
183+ assert len (result.rows) == 1
184+ assert result.rows[0 ][" name" ] == " Test"
185+ ```
186+
187+ ### 7. Document Your Backend
188+
189+ Add documentation explaining:
190+ - Connection string format (e.g., ` mybackend://host:port/database ` )
191+ - Any special configuration options
192+ - Limitations or backend-specific features
193+ - Example usage in notebooks
194+
195+ ### Best Practices
196+
197+ 1 . ** Handle Errors Gracefully** : Provide clear error messages for connection failures and unsupported operations
198+ 2 . ** Type Mapping** : Implement proper type mapping between LinkML types and your backend's native types
199+ 3 . ** Performance** : Consider implementing batch operations for better performance
200+ 4 . ** Schema Support** : If your backend supports schemas, integrate with LinkML's schema validation
201+ 5 . ** Indexing** : Implement index creation/management if supported by your backend
202+ 6 . ** Query Translation** : Convert LinkML queries to your backend's query language
203+
204+ ### Example Backends to Study
205+
206+ Look at these existing implementations for reference:
207+ - ` duckdb ` : SQL-based backend with array support
208+ - ` mongodb ` : Document-based NoSQL backend
209+ - ` filesystem ` : File-based storage using JSON/YAML/CSV files
210+ - ` neo4j ` : Graph database backend
0 commit comments