paint-brush
FastAPI में रिपॉजिटरी पैटर्न का उपयोग करके कुशल सत्र संचालनद्वारा@abram
5,678 रीडिंग
5,678 रीडिंग

FastAPI में रिपॉजिटरी पैटर्न का उपयोग करके कुशल सत्र संचालन

द्वारा Abram9m2023/06/09
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

डेटा निरंतरता बनाए रखने, त्रुटियों को रोकने और बैकएंड सिस्टम की स्थिरता सुनिश्चित करने के लिए कुशल सत्र प्रबंधन महत्वपूर्ण है। सर्वोत्तम प्रथाओं का पालन करके, जैसे कि संदर्भ प्रबंधकों का उपयोग करना और रिपॉजिटरी पैटर्न को अपनाना, डेवलपर्स मजबूत और विश्वसनीय सिस्टम बना सकते हैं जो सत्र को प्रभावी ढंग से प्रबंधित करते हैं और डेटाबेस लेनदेन के दौरान त्रुटियों को संभालते हैं।
featured image - FastAPI में रिपॉजिटरी पैटर्न का उपयोग करके कुशल सत्र संचालन
Abram HackerNoon profile picture

मैंने लगभग पांच महीने पहले FastAPI के साथ रिपॉजिटरी पैटर्न को अपनाने के बारे में एक लेख लिखा था, और मुझे बहुत कुछ पढ़ने को मिला (धन्यवाद)। मैं अभी भी रिपोजिटरी पैटर्न का उपयोग कर सत्र प्रबंधन को संभालने के एक प्रभावी तरीके के बारे में लिखने आया हूं।


इससे पहले कि मैं इसमें सीधे कूदता, मैंने देखा कि उत्पादन पर, मुझे निम्न में से कोई भी त्रुटि मिलती है जब भी मेरे एपीआई लेनदेन करने की कोशिश कर रहे हैं जिसमें डेटाबेस को पढ़ना या लिखना शामिल है:


  • sqlalchemy.exc.PendingRollbackError
  • sqlalchemy.exc.InvalidRequestError

sqlalchemy.exc.PendingRollbackError

यह त्रुटि इंगित करती है कि एक अप्रतिबंधित लेनदेन प्रगति पर है जिसे किसी अन्य डेटाबेस संचालन के साथ आगे बढ़ने से पहले रोलबैक करने की आवश्यकता है।


इस त्रुटि का सबसे आम कारण एक डेटाबेस लेनदेन के दौरान होने वाला एक अनियंत्रित अपवाद है, जो लेनदेन को कमिट होने या ठीक से रोल बैक करने से रोकता है।

sqlalchemy.exc.InvalidRequestError

यह त्रुटि इंगित करती है कि आपके द्वारा डेटाबेस में किया गया कोई ऑपरेशन या अनुरोध अमान्य है या समर्थित नहीं है। इस त्रुटि के विभिन्न कारण हो सकते हैं, जिनमें निम्न शामिल हैं:


  • SQLAlchemy API का गलत उपयोग, जैसे किसी विधि को कॉल करना या किसी विशेषता को एक्सेस करना जो मौजूद नहीं है या दिए गए संदर्भ में लागू नहीं है।


  • गलत SQL सिंटैक्स या क्वेरी संरचना।


  • पायथन ऑब्जेक्ट्स और डेटाबेस टेबल/कॉलम के बीच मिसिंग या गलत मैपिंग।


मुझे यकीन है कि आपके पास इस बारे में विचार हैं कि इन त्रुटियों को कैसे हल किया जा सकता है, हालांकि, मैं यह बताना चाहता हूं कि भले ही मैंने पहचान की कि समस्या क्या थी और इसे ठीक किया- समस्या बनी रहती है।


यदि आप उत्सुक हैं कि मैं कैसे उनका निवारण और समाधान करता हूं, तो आप निम्न चरणों का पालन करने पर विचार कर सकते हैं:

sqlalchemy.exc.लंबित रोलबैक त्रुटि:

  • किसी भी हैंडल न किए गए अपवाद के लिए अपने कोड की समीक्षा करें जो लेन-देन को प्रतिबद्ध होने या ठीक से रोल बैक करने से रोक सकता है। सुनिश्चित करें कि आप अपवादों को ठीक से संभाल रहे हैं और आवश्यकतानुसार लेन-देन कर रहे हैं या वापस कर रहे हैं।


  • किसी भी लंबे समय से चल रहे या नेस्टेड लेन-देन की जाँच करें जिससे लंबित रोलबैक हो सकते हैं। सुनिश्चित करें कि सभी लेन-देन प्रतिबद्ध हैं या समयबद्ध तरीके से वापस ले लिए गए हैं।


  • किसी भी मामले के लिए अपने कोड की समीक्षा करें जहां आप पिछले लेन-देन को ठीक से संभालने से पहले एक नया लेन-देन शुरू कर सकते हैं।

sqlalchemy.exc.InvalidRequestError:

  • अमान्य अनुरोध के कारण की पहचान करने के लिए अपवाद के साथ प्रदान किए गए विशिष्ट त्रुटि संदेश की समीक्षा करें। यह आपको संकेत दे सकता है कि आपके कोड या SQL कथन का कौन सा हिस्सा समस्या पैदा कर रहा है।


  • किसी भी गलत विधि कॉल, एट्रिब्यूट एक्सेस या API के गलत उपयोग के लिए अपने SQLAlchemy कोड की जाँच करें।


  • यह सुनिश्चित करने के लिए कि उनके पास सही सिंटैक्स और संरचना है, अपने SQL कथनों की समीक्षा करें।


  • सत्यापित करें कि आपका डेटाबेस स्कीमा और SQLAlchemy मैपिंग सिंक में हैं। सुनिश्चित करें कि सभी आवश्यक टेबल और कॉलम मौजूद हैं और यह कि आपके पायथन ऑब्जेक्ट्स को संबंधित डेटाबेस संस्थाओं के लिए ठीक से मैप किया गया है।


आइए देखें कि मैंने एक स्थायी समाधान पर कैसे काम किया जो मेरे लिए कारगर साबित हुआ है। मैं उस प्रोजेक्ट का उपयोग करने के लिए आगे बढ़ूंगा जिस पर मैंने काम किया था जब मैं रिपॉजिटरी पैटर्न का उपयोग करने का तरीका दिखा रहा था।


हमारे पास एक मॉड्यूल था जहां हमने निम्नलिखित कोड के साथ अपने ओआरएम बेस सत्र मिश्रण को संग्रहित किया था:


 # SQLAlchemy Imports from sqlalchemy.orm import Session # Own Imports from config.database import SessionLocal from core.settings import ledger_settings class ORMSessionMixin: """Base orm session mixin for interacting with the database.""" def __init__(self): """ Get the next database session from the database pool. """ self.orm: Session = self.get_db().__next__() def get_db(self): """ This method creates a database session, yields it, rollback the transaction if there's an exception and then finally closes the session. Yields: db: scoped database session """ db = SessionLocal() try: yield db except Exception: db.rollback() finally: db.close()


इस समाधान के साथ समस्या यह थी कि यदि लेन-देन की प्रक्रिया में कोई अपवाद होता है (यह कुछ भी हो सकता है: एक उपयोगकर्ता बनाना, अपने बटुए को निधि देना, आदि) - अपवादों को ठीक से नियंत्रित नहीं किया जाता है, और पारगमन में डेटाबेस सत्र नहीं होता है रोलबैक प्राप्त करें।


तीन महीने के डिबगिंग और पैचिंग और बहुत सारे शोध के बाद, मैं आखिरकार सत्रों को संभालने का एक कुशल तरीका बनाने में सक्षम था।


 # SQLAlchemy Imports import sqlalchemy from sqlalchemy.orm import Session # Own Imports from config.database.connection import SessionLocal class DatabaseSessionMixin: """Database session mixin.""" def __enter__(self) -> Session: self.db = SessionLocal() return self.db def __exit__(self, exc_type, exc_val, exc_tb): try: if exc_type is not None: self.db.rollback() except sqlalchemy.exc.SQLAlchemyError: pass finally: self.db.close() SessionLocal.remove() def use_database_session(): return DatabaseSessionMixin()


इस कोड में:


  • DatabaseSession एक संदर्भ प्रबंधक वर्ग है जो सत्र को संभालता है और यह सुनिश्चित करता है कि यह ठीक से बंद हो और किसी त्रुटि के मामले में वापस लुढ़का हो।


  • __enter__ विधि सत्र को प्रारंभ करती है और इसे वापस करती है।


  • __exit__ विधि अपवादों की जांच करती है और अपवाद होने पर सत्र को वापस ले जाती है। इसके बाद यह सत्र को बंद कर देता है और इसे दायरे वाले सत्र से हटा देता है।


  • use_database_session एक यूटिलिटी फंक्शन है जिसका उपयोग सत्र उपयोग को आसान बनाने के लिए डेकोरेटर या संदर्भ प्रबंधक के रूप में किया जा सकता है।


यहां एक उदाहरण दिया गया है कि आप use_database_session उपयोगिता फ़ंक्शन का उपयोग कैसे कर सकते हैं:


 with use_database_session() as db: # perform logic that uses the session # ... # After exiting the context, the session will be automatically closed and removed from the scoped session.


उपरोक्त दृष्टिकोण सत्रों को संभालने के लिए एक स्वच्छ और अधिक कुशल तरीका प्रदान करता है और यह सुनिश्चित करता है कि त्रुटि के मामले में उन्हें ठीक से वापस ले लिया जाए या बंद कर दिया जाए। आइए आगे बढ़ते हैं कि आप ORM में डेटाबेस सत्र का उपयोग करते समय रिपॉजिटरी पैटर्न को कैसे लागू करते हैं।


 # SQLAlchemy Imports import sqlalchemy from sqlalchemy.orm import Session class BaseRepository: def __init__(self, session: Session): self.db = session class UserRepository(BaseRepository): """Operations to interact with the `users` table in the database.""" def get(self, user_id: int) -> User: """This method gets a user from the database.""" user = ( self.db.query(User) .filter(User.id == user_id) .first() ) return user def create(self, name: str, email: str, password: str) -> User: """This method creates a user.""" user = User(name=name, email=email, password=password) self.db.add(user) self.db.commit() self.db.refresh(user) return user def update_user(self, user_id: int, updated_data: dict): """This method updates a user.""" user = self.get(user_id) if user: for key, value in updated_data.items(): setattr(user, key, value) self.db.commit() return user return None def delete_user(self, user_id): """This method deletes a user.""" user = self.get_user(user_id) if user: self.db.delete(user) self.db.commit() return True return False


इसके बाद उपरोक्त भंडार को आपके आवेदन की सेवा परत में एकीकृत करना होगा। मान लीजिए कि आपके पास एक सेवा कार्य है जो उपयोगकर्ता खाता बनाता है; यहां बताया गया है कि आप इसे हमारी नई पद्धति का उपयोग करके कैसे करेंगे:


 # Apps Imports from apps.users.models import User from apps.users.repo import UserRepository from apps.users.schemas.auth import UserCreate # Config Imports from config.security.hashers import password from config.database.session_mixin import use_database_session async def create_user(user: UserCreate) -> User: """ This function creates a new user in the database. :param user: schemas.UserCreate :type user: schemas.UserCreate :return: The user object """ with use_database_session() as db: users_repo = UserRepository(db) user = users_repo.create( user.name, user.email, password.hash(user.password) ) return user


उपरोक्त पैटर्न आपको विरासत में मिले डेटाबेस सत्र का लाभ उठाते हुए डेटाबेस संचालन को रिपॉजिटरी कक्षाओं में समाहित करने की अनुमति देगा। यह आपके ORM मॉडल और रिपॉजिटरी लॉजिक के बीच एक स्पष्ट अलगाव भी प्रदान करता है।

निष्कर्ष

अंत में, बैकएंड सिस्टम बनाते समय सत्रों का कुशल संचालन महत्वपूर्ण है।


डेटाबेस लेनदेन के दौरान होने वाली sqlalchemy.exc.PendingRollbackError और sqlalchemy.exc.InvalidRequestError जैसी त्रुटियां डेटा असंगतता और एप्लिकेशन विफलताओं का कारण बन सकती हैं यदि ठीक से संभाला न जाए।


सिस्टम की अखंडता और विश्वसनीयता को बनाए रखने के लिए इन त्रुटियों की पहचान करना और उनका समाधान करना महत्वपूर्ण है।


सत्र प्रबंधन से संबंधित मुद्दों को हल करने के लिए, मजबूत रणनीतियों को लागू करना आवश्यक है। एक दृष्टिकोण संदर्भ प्रबंधकों का उपयोग करना है, जैसे कि DatabaseSessionMixin जिसे हमने लेख में प्रदर्शित किया है।


यह संदर्भ प्रबंधक सुनिश्चित करता है कि अपवादों के मामले में सत्र ठीक से खुले, बंद और लुढ़के हुए हैं। संदर्भ प्रबंधक के भीतर सत्र तर्क को समाहित करके, आप सत्र प्रबंधन को सुव्यवस्थित कर सकते हैं और त्रुटि से निपटने में सुधार कर सकते हैं।


इसके अतिरिक्त, एप्लिकेशन के सर्विस लेयर में रिपॉजिटरी पैटर्न को एकीकृत करने से सेशन हैंडलिंग की दक्षता में और वृद्धि हो सकती है।


डेटाबेस ऑपरेशंस को रिपॉजिटरी क्लासेस में अलग करके और संदर्भ प्रबंधक से विरासत में मिले सत्र का लाभ उठाकर, आप क्लीनर कोड संगठन प्राप्त कर सकते हैं और ORM मॉडल और रिपॉजिटरी लॉजिक के बीच स्पष्ट अलगाव बनाए रख सकते हैं।


कुल मिलाकर, कुशल सत्र प्रबंधन डेटा स्थिरता बनाए रखने, त्रुटियों को रोकने और बैकएंड सिस्टम की स्थिरता सुनिश्चित करने के लिए महत्वपूर्ण है।


सर्वोत्तम प्रथाओं का पालन करके, जैसे कि संदर्भ प्रबंधकों का उपयोग करना और रिपॉजिटरी पैटर्न को अपनाना, डेवलपर्स मजबूत और विश्वसनीय सिस्टम बना सकते हैं जो सत्रों को प्रभावी ढंग से प्रबंधित करते हैं और डेटाबेस लेनदेन के दौरान त्रुटियों को संभालते हैं।


मैं गिग्स लिखने और सक्रिय रूप से अनुबंध भूमिकाओं की खोज करने के लिए खुला हूं जिसमें पायथन (Django, FastAPI, आदि) के साथ निर्माण शामिल है।