Uncategorized Archives - Moringa School https://moringaschool.com Nurturing Africa's Tech Talent Mon, 22 Jan 2024 06:25:26 +0000 en-US hourly 1 https://wordpress.org/?v=6.2.5 https://moringaschool.com/wp-content/uploads/2022/02/cropped-favicon-32x32.png Uncategorized Archives - Moringa School https://moringaschool.com 32 32 Exploring Events and Event Listeners in SQLAlchemy ORM https://moringaschool.com/blog/exploring-events-and-event-listeners-in-sqlalchemy-orm/ https://moringaschool.com/blog/exploring-events-and-event-listeners-in-sqlalchemy-orm/#comments Mon, 22 Jan 2024 06:23:39 +0000 https://moringaschool.com/?p=5543 In SQLAlchemy, events and event listeners provide a powerful mechanism for executing custom code in response to specific actions or changes within the ORM. These can be particularly useful for scenarios like tracking changes, sending notifications, or enforcing business logic. This blog will delve into the concept of events and event listeners in SQLAlchemy ORM […]

The post Exploring Events and Event Listeners in SQLAlchemy ORM appeared first on Moringa School.

]]>

In SQLAlchemy, events and event listeners provide a powerful mechanism for executing custom code in response to specific actions or changes within the ORM. These can be particularly useful for scenarios like tracking changes, sending notifications, or enforcing business logic. This blog will delve into the concept of events and event listeners in SQLAlchemy ORM using a practical example.

Understanding the Code Snippet

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
from sqlalchemy import Enum as EnumType

class Status(str, Enum):
    PENDING = "pending"
    REJECTED = "rejected"
    APPROVED = "approved"

class FuelRequest(AbstractBaseModel):
    __tablename__ = "fuels"

    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    public_id = Column(String(50), unique=True)
    status = Column(EnumType(Status), default=Status.PENDING)
    user_id = Column(Integer, ForeignKey("users.id"))
    user = relationship("User", back_populates="fuels")
from sqlalchemy import event
from sqlalchemy.orm.attributes import get_history
from ..utils import get_db

def track_status_changes(mapper, connection, target):
    # Get the history of the 'status' attribute
    hist = get_history(target, 'status')

    if hist.has_changes():
        # Get the user's phone number
        db = next(get_db())
        user_phone_number = get_user_phone_number(db, user_id=target.user_id)

        # Create a message
        message = f"The status of your {target.__class__.__name__} Request has changed to {target.status}."
        # send_notification(user_phone_number, message)
        send_sms_notification(user_phone_number, message)

# Add the event listeners
event.listen(FuelRequest, 'after_update', track_status_changes)

In this example, an event listener named track_status_changes is defined. This listener is triggered after an update operation ('after_update') on instances of the FuelRequest classes. The listener checks if the ‘status’ attribute of the target object has changed. If so, it retrieves the user’s phone number and sends an SMS notification about the status change.

Breaking Down the Code

Defining the Event Listener

def track_status_changes(mapper, connection, target):
    # Get the history of the 'status' attribute
    hist = get_history(target, 'status')

    if hist.has_changes():
        # Get the user's phone number
        db = next(get_db())
        user_phone_number = get_user_phone_number(db, user_id=target.user_id)

        # Create a message to be sent
        message = f"The status of your {target.__class__.__name__} Request has changed to {target.status}."
        # Call the  send_sms_notification to send the message to the user using the users phone number
        send_sms_notification(user_phone_number, message)

The track_status_changes function is the event listener. It takes three

parameters: mapperconnection, and target.

The mapper parameter refers to ORM Mapper for the object.


The connection parameter refers to the database connection in use.


The target parameter refers to the instance of the class (e.g. FuelRequest) that triggered the event.

Inside the listener, it checks if the ‘status’ attribute has changed and, if so, retrieves the user’s phone number and sends an SMS notification.

import os
from twilio.rest import Client
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

account_sid = os.environ['ACCOUNT_SID']
auth_token = os.environ['AUTH_TOKEN']
phone_number = os.environ['TWILIO_PHONE_NUMBER']
client = Client(account_sid, auth_token)

def get_user_phone_number(db, user_id: int):
    # get the user
    user = db.query(User).filter(User.id == user_id).first()
    # return the user's phone number
    return user.phone_number if user else None

def send_sms_notification(user_phone_number, message_body):
    try:
        message = client.messages.create(
            body=message_body,
            from_= phone_number,  # Your Twilio phone number
            to=user_phone_number  # Get the user phone numbr from the User model
        )
    except Exception as e:
        raise ValueError("Error occurred while sending message: ", e)

Adding Event Listeners

event.listen(FuelRequest, 'after_update', track_status_changes)

The event.listen method is used to attach the track_status_changes listener to the

‘after_update’ event of the specified classes ( FuelRequest). This means that the listener will be

executed every time an instance of these classes undergoes an update operation.

Conclusion

Events and event listeners in SQLAlchemy provide a flexible way to incorporate custom behavior into your ORM-based applications. Whether you need to track changes, enforce business rules, or send notifications, event listeners offer a clean and modular solution. The provided code snippet demonstrates how to use event listeners to respond to updates in the ‘status’ attribute of different ORM entities. Feel free to adapt and extend this example to suit your specific application needs. Happy coding! 🚀💻

The post Exploring Events and Event Listeners in SQLAlchemy ORM appeared first on Moringa School.

]]>
https://moringaschool.com/blog/exploring-events-and-event-listeners-in-sqlalchemy-orm/feed/ 1
ORM Mapped Class Configuration in SQLAlchemy https://moringaschool.com/blog/orm-mapped-class-configuration-in-sqlalchemy/ https://moringaschool.com/blog/orm-mapped-class-configuration-in-sqlalchemy/#respond Tue, 09 Jan 2024 08:05:35 +0000 https://moringaschool.com/?p=5492 Let’s embark on a journey into the enchanting realm of SQLAlchemy, where Object-Relational Mapping (ORM) adds a layer of magic to database interactions. We’ll unravel the secrets of configuring Mapped Classes, the wizards behind the scenes. Understanding ORM Mapped Classes In SQLAlchemy, Mapped Classes serve as the bridge between the world of objects in your […]

The post ORM Mapped Class Configuration in SQLAlchemy appeared first on Moringa School.

]]>

Let’s embark on a journey into the enchanting realm of SQLAlchemy, where Object-Relational Mapping (ORM) adds a layer of magic to database interactions. We’ll unravel the secrets of configuring Mapped Classes, the wizards behind the scenes.

Understanding ORM Mapped Classes

In SQLAlchemy, Mapped Classes serve as the bridge between the world of objects in your code and the rows in your database tables. To make this magic happen, let’s explore the essential configurations for Mapped Classes.

Creating a Mapped Class

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class YourModel(Base):
    __tablename__ = 'your_table_name'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

Here, YourModel becomes the hero of your database story, with attributes corresponding to the columns in your table.

Defining Relationships

The beauty of SQLAlchemy lies in its ability to represent relationships between tables effortlessly. Let’s say you have another model, AnotherModel, and you want to establish a relationship between them.

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class AnotherModel(Base):
    __tablename__ = 'another_table'

    id = Column(Integer, primary_key=True)
    something_else = Column(String)
    
    your_model_id = Column(Integer, ForeignKey('your_model.id'))
    your_model = relationship('YourModel', back_populates='another_models')

Here, the relationship attribute creates a connection between the two models, enabling you to navigate the relationships seamlessly.

Additional Configuration Options

  1. Customizing Table Names
    If your class name and table name aren’t a perfect match, you can specify it using __tablename__:

your_model = relationship('YourModel', back_populates='another_models', uselist=False)

2. Handling Relationships
Use the relationship attribute to define relationships, specifying details like back-references and joining conditions.

your_model = relationship('YourModel', back_populates='another_models', uselist=False)

3. Indexing Columns
Improve query performance by adding indexes to columns:

name = Column(String, index=True)

Bringing It All Together

from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class YourModel(Base):
    __tablename__ = 'your_table_name'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    age = Column(Integer)

    another_models = relationship('AnotherModel', back_populates='your_model')

class AnotherModel(Base):
    __tablename__ = 'another_table'

    id = Column(Integer, primary_key=True)
    something_else = Column(String)
    
    your_model_id = Column(Integer, ForeignKey('your_model.id'))
    your_model = relationship('YourModel', back_populates='another_models')

There you have it! With the power of ORM Mapped Class Configuration in SQLAlchemy, you’re ready to weave complex relationships and transform your database interactions into a magical experience. Happy coding! 🚀💻

The post ORM Mapped Class Configuration in SQLAlchemy appeared first on Moringa School.

]]>
https://moringaschool.com/blog/orm-mapped-class-configuration-in-sqlalchemy/feed/ 0
SQLAlchemy Object Relational Mapper (ORM) State Management https://moringaschool.com/blog/sqlalchemy-object-relational-mapper-orm-state-management/ https://moringaschool.com/blog/sqlalchemy-object-relational-mapper-orm-state-management/#respond Mon, 08 Jan 2024 10:52:26 +0000 https://moringaschool.com/?p=5457 Object-Relational Mapping (ORM) is a technique that lets you query and manipulate data from a database using an object-oriented paradigm. When talking about ORM, most people are referring to a library that implements the Object-Relational Mapping technique, hence the phrase “an ORM”. An ORM library is a completely ordinary library written in your language of choice that encapsulates […]

The post SQLAlchemy Object Relational Mapper (ORM) State Management appeared first on Moringa School.

]]>

Object-Relational Mapping (ORM) is a technique that lets you query and manipulate data from a database using an object-oriented paradigm. When talking about ORM, most people are referring to a library that implements the Object-Relational Mapping technique, hence the phrase “an ORM”.

An ORM library is a completely ordinary library written in your language of choice that encapsulates the code needed to manipulate the data, so you don’t use SQL anymore; you interact directly with an object in the same language you’re using.

For example, here is a completely imaginary case with a pseudo language:

You have a book class, you want to retrieve all the books of which the author is “biko”. Manually, you would do something like that:

book_list = new List();
sql = "SELECT book FROM library WHERE author = 'biko'";
data = query(sql); // I over simplify ...
while (row = data.next())
{
     book = new Book();
     book.setAuthor(row.get('author');
     book_list.add(book);
}

SQLAlchemy

SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL.

It provides a full suite of well known enterprise-level persistence patterns, designed for efficient and high-performing database access, adapted into a simple and Pythonic domain language.

Managing the state of your data is crucial for robust applications, and SQLAlchemy ORM offers a powerful toolkit for handling this with elegance and efficiency. 💼

In SQLAlchemy, the ORM layer helps us bridge the gap between the relational database and our Python code, making it seamless to work with database records as Python objects. 🐍

Key points on state management with SQLAlchemy ORM:

  • Identity Map Pattern: SQLAlchemy keeps track of objects in a unit of work using the Identity Map pattern. This ensures that each database row is represented by a single Python object within a session.
  • Session State: The Session in SQLAlchemy acts as a staging area for all changes before committing them to the database. Understanding and managing session states is vital for a smooth workflow.
  • Dirty Tracking: SQLAlchemy automatically tracks changes to objects and only updates the fields that have been modified. This minimizes unnecessary database updates, optimizing performance.
  • Unit of Work Pattern: SQLAlchemy employs the Unit of Work pattern to coordinate changes and transactions, making it easier to manage complex operations involving multiple objects.
  • Flushing and Committing: Explicitly flushing the session synchronizes changes with the database, and committing finalizes the transaction. Understanding when to flush and commit is essential for data integrity.
  • Events and Hooks: SQLAlchemy provides a rich set of events and hooks, allowing customization of state management behaviors to suit specific application needs.

Assume you have a User model representing users in a database:

from sqlalchemy import create_engine, Column, Integer, String, Sequence
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

# Define the User model
Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String(50))
    age = Column(Integer)

# Create an SQLite in-memory database and bind the engine
engine = create_engine('sqlite:///:memory:')

# Create the 'users' table in the database
Base.metadata.create_all(engine)

# Create a Session class to interact with the database
Session = sessionmaker(bind=engine)
session = Session()

Now, let’s explore state management:

# Create a new user and add it to the session
new_user = User(name='John Doe', age=25)
session.add(new_user)

# At this point, the user is in the 'Pending' state, not yet committed to the database

# Query the user (this will trigger a flush to the database)
queried_user = session.query(User).filter_by(name='John Doe').first()

# The queried_user is now in the 'Persistent' state, representing a database record

# Modify the user's age
queried_user.age = 26

# At this point, SQLAlchemy has marked the user as 'Dirty' because it has been modified

# Commit the changes to the database
session.commit()

# Now, the changes are saved to the database, and the user is in the 'Committed' state

# The session is now in a 'Clean' state, and the user is no longer marked as 'Dirty'

In this example:

  • Pending: When a new user is added to the session, it is in a pending state.
  • Persistent: After querying a user from the database, it becomes persistent.
  • Dirty: If you modify a persistent object, it becomes dirty.
  • Committed: After committing changes, the object is in a committed state.
  • Clean: The session is clean after committing, and the object is no longer dirty.

Understanding these states helps you manage your data effectively when working with SQLAlchemy ORM. Feel free to experiment and build upon this example!

The post SQLAlchemy Object Relational Mapper (ORM) State Management appeared first on Moringa School.

]]>
https://moringaschool.com/blog/sqlalchemy-object-relational-mapper-orm-state-management/feed/ 0
Leading Investor, Proparco (AFD Group), Completes Pre-Series-A Investment in Moringa Fueling its Expansion across Africa https://moringaschool.com/blog/leading-investor-proparco-afd-group-completes-pre-series-a-investment-in-moringa-fueling-its-expansion-across-africa/ https://moringaschool.com/blog/leading-investor-proparco-afd-group-completes-pre-series-a-investment-in-moringa-fueling-its-expansion-across-africa/#respond Thu, 23 Jun 2022 14:34:24 +0000 https://moringaschool.com/?p=2731 Building on the Seed Investment by DOB Equity and USD 9.5m funding by Mastercard Foundation, Moringa is excited to have recently received an investment from Proparco to support its expansion outside Kenya. This has seen the tech-based learning institution start to train Software Engineers in Ghana and soon Nigeria with a plan to scale to […]

The post Leading Investor, Proparco (AFD Group), Completes Pre-Series-A Investment in Moringa Fueling its Expansion across Africa appeared first on Moringa School.

]]>

Building on the Seed Investment by DOB Equity and USD 9.5m funding by Mastercard Foundation, Moringa is excited to have recently received an investment from Proparco to support its expansion outside Kenya. This has seen the tech-based learning institution start to train Software Engineers in Ghana and soon Nigeria with a plan to scale to other African countries in the next 12 months. Moringa, a career accelerator for Tech professionals in Africa, has been training High School/University Graduates to be Software Engineers and Data Scientists for the past 7 years in Kenya and achieved market leadership training over 4,000 students with an employment rate of over 85%.

The investment comes at an exciting time with Moringa just agreeing to a curriculum licensing deal with the world’s leading coding boot camp, Flatiron School, and achieving ISO 9001:2015 certification. The stage is set for Moringa to play a significant role in developing African tech talent and connecting it to purposeful and significant earning opportunities whether full-time jobs, the gig economy, or becoming entrepreneurs.


Google published the Africa Developer Ecosystem report in 2021 which indicates that there has been an increased global demand for remote tech talent which was accelerated by the pandemic, creating more employment opportunities for African technology professionals. The report indicates that African startups which are responsible for hiring more than half of the local developers raised over $4 Billion in 2021 -2.5X more than they raised in 2020. With 22% of Sub-Saharan small and medium-sized businesses starting or increasing their use of the internet, the need for web development skills is increasing rapidly. Higher demand for remote development work also led to increased opportunities; 38% of African developers work for at least one company based outside the continent.


Moringa provides access for all to the training and network needed to participate in this tech revolution if they can demonstrate they have the aptitude and mindset required to succeed. This is part of the company’s mission to build talent and opportunities through tech-based learning experiences. Following our recent launches with Impact Hub Accra and Social Enterprise Ghana, Moringa and Plenty Tech Jobs Nigeria have entered into a market entry partnership that will see Moringa become a key provider of tech talent for the Nigerian workforce. Plenty Tech Jobs is a leading platform for finding the best technology job and remote gigs in Nigeria.


The investment from Proparco will aid Moringa to prepare for Series A funding in 2023. Apart from International expansion outside Kenya, the funding from Proparco will also facilitate the broadening of the range of courses offered by Moringa. Currently, the institution offers Software Engineering, Data Science, and Soft Skills courses with plans to offer courses in UI/UX design in the near future.


Statement from Moringa
According to Snehar Shah, Moringa’s CEO “The investment comes at an exciting time for Moringa as the institution expands to Ghana and Nigeria. We are keen to leverage this partnership to train many more students using the leading US Bootcamp curriculum from Flatiron School. In line with our vision of a world in which anyone can create their future, we welcome the support of Proparco to make our courses available in new markets in Africa.”


Statement from Proparco
According to Françoise Lombard, Proparco’s CEO “Supporting the African tech ecosystem is one of Proparco’s key priorities. Through our investment in Moringa, Proparco is proud to support an ambitious Edtech in its expansion in Africa and thus contribute to bridging the skills gap that has been affecting the growth of startups on the African continent”.


About Moringa
Moringa is a multi-disciplinary learning accelerator committed to closing the skills gap in Africa’s job market by providing transformative tech-based learning. Founded in April 2014, Moringa School plays a pivotal role in developing and nurturing high-potential individuals who are passionate about technology and want to take a lead role in Software Engineering and other tech-based programs.


Moringa prides itself on training 4,000+ students and placing more than 85% of its graduates into leading companies throughout Africa and the world. Some of the notable companies that our graduates have been placed in include Safaricom, I&M, Andela, Sanlam, Microsoft, Cybertek, and Dalberg Data Insights. In 2020, Moringa was listed among the top 50 Edtech companies in Africa by HolonIQ. The World Bank cited Moringa School as a leader in the space following its research into technology boot camps. Most recently, Moringa School was selected as one of the World Economic Forum’s “Technology Pioneers in 2021.”


Through a distinctive learning model and a curriculum partnership with Flatiron School, the no.1 US boot camp, Moringa is creating world-class developers in Africa.


For more information about Moringa, visit: https://moringaschool.com.
steve.nyikuli@moringaschool.com – Mobile: +254 719 407816


About Proparco
Proparco is the private sector financing arm of Agence Française de Développement Group (AFD Group). It has been promoting sustainable economic, social and environmental development for over 40 years. Proparco provides funding and support to both businesses and financial institutions in Africa, Asia, Latin America, and the Middle East. Its action focuses on the key development sectors: infrastructure, mainly for renewable energies, agribusiness, financial institutions, health, and education.
Its operations aim to strengthen the contribution of private players to the achievement of the Sustainable Development Goals (SDGs) were adopted by the international community in 2015. To this end, Proparco finances companies whose activity contributes to creating jobs and decent incomes, providing essential goods and services, and combating climate change. For a World in Common.

For further information: visit www.proparco.fr and or follow @Proparco

The post Leading Investor, Proparco (AFD Group), Completes Pre-Series-A Investment in Moringa Fueling its Expansion across Africa appeared first on Moringa School.

]]>
https://moringaschool.com/blog/leading-investor-proparco-afd-group-completes-pre-series-a-investment-in-moringa-fueling-its-expansion-across-africa/feed/ 0