Databases Artifact

This artifact seeks to update a MongoDB CRUD module into a module that run both relational and non-relational paradigms in parallel. It uses a database-agnostic abstraction layer to achieve this.

Code Review

Artifacts

Original Artifact

Initial monolithic Python module for MongoDB CRUD operations.

Enhanced Artifact

Refactored modular Python module that utilizes database-agnostic abstraction to support operations between both paradigms.

Narrative

Description

The artifact I selected for this enhancement is the AnimalShelter CRUD module originally created for my CS-340: Client/Server Development course. The module provides Create, Read, Update, and Delete (CRUD) operations for the AAC animal dataset stored in MongoDB. It establishes a connection to the MongoDB instance, validates user inputs, and performs CRUD operations on the “animals” collection.

For this milestone, I originally planned to enhance the module by re-implementing it in a way that supports both NoSQL (MongoDB) and a SQL-based relational database (SQLite). As I worked through the enhancement, the scope increased to also make it so that the SQL module would use the same dictionary structures as mongo database, ensuring that the transition between the two paradigms was seamless. My approach to this problem was to have a backend function within my wrapper module to explicitly convert a dictionary to a proper SQL statement, requiring no additional work from any code relying on the module.

Justification For Inclusion

I selected this artifact because it demonstrates my ability to apply data structure and algorithmic principles to real-world database systems. I also show a strong understanding of encapsulation by breaking the refactored code into a modulated file system, breaking each working component together. Some core competencies that I feel this enhancement covers are:

  • Database Abstraction and Design: I achieved this by implementing a unifying interface layer that separates any client logic from the underlying database implementation. This is specifically evident in the fact that the client can use the same dictionary object to execute queries, despite SQL operating on a completely different (relational) query paradigm.
  • Cross-Paradigm CRUD Operations: I demonstrate that I can define efficient CRUD logic across both document-based and relational schemas.
  • Software Engineering Principles: I demonstrate competency in this area by refactoring the original one file CRUD file into a modular design. Allowing for any client-side interface to quickly use the module without having to interact with the underlying database workings.


Overall, this enhancement illustrates adaptability in working with different database technologies and highlights my ability to write clean, reusable, and database-agnostic code between differing paradigms.

Course Outcomes and Enhancement Alignment

This enhancement aligns directly with these course outcomes:

  • Design and evaluate computing solutions that solve a given problem using algorithmic principles and computer science practices. CRUD is a fundamental computing solution, seamlessly implementing it across two database paradigms demonstrates strong algorithmic and design reasoning.
  • Demonstrate an ability to use well-founded and innovative techniques, skills, and tools in computing practices. Using MongoDB and SQLite shows my versatility in deploying appropriate database tools for different problem domains. Having a strong understanding of both relational and non-relational databases is a cornerstone of being a Software Engineer.
  • Employ strategies for building collaborative environments. By abstracting the CRUD implementation into a database agnostic layer, I am making collaboration easier. E.G if a corporation uses my module for both paradigms, there isn’t a need for two different query sets to be written in the native implementations. My enhancement abstracts this, and will allow for quick integration between either or.

Reflection on the Enhancement Process

Enhancing this artifact provided valuable insights into designing for flexibility and balancing trade-offs across different database paradigms.
I deepened my understanding of the differences in schema design, query patterns, and efficiency trade offs between SQL and NoSQL. For example, MongoDB excels at handling unstructured data and dynamic schemas, while SQLite requires strict relational schema design but offers strong data integrity.

My biggest challenge was designing a unified abstraction layer that could adequately represent both paradigms, in a unified manner. MongoDB queries return JSON like objects, as well as take them for queries, while SQLite queries return tabular rows and require relational querying. Bridging these inputs and outputs into common formats required me to make deliberate design choices for the end paradigm of my abstraction layer.
I solved this problem by defining an abstract crud interface that always returns data in a normalized Python dictionary or list-of-dictionaries format. This way, the client code never has to differ between data that came from MongoDB or SQLite.

Ultimately, this enhancement strengthened my ability to think in terms of abstraction layers. It helped me with designing APIs and code structures that hide complexity from the client while maintaining flexibility for future upgrades.