Introduction
In today’s digital landscape, the creation of shorter, more manageable URLs is essential. This tutorial will guide you through using SQLAlchemy to design a database for a shortened URL service, following a step-by-step approach.
Getting Started with SQLAlchemy
SQLAlchemy is a Python SQL toolkit and Object-Relational Mapping (ORM) library that provides a full suite of well-known enterprise-level persistence patterns. First, ensure you have SQLAlchemy installed:
pip install SQLAlchemy
Now, let’s start by setting up a basic model for our URL shortening service:
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
Base = declarative_base()
class ShortenedUrl(Base):
__tablename__ = 'shortened_urls'
id = Column(Integer, primary_key=True)
original_url = Column(String, nullable=False)
short_code = Column(String(10), unique=True, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
# Create the engine linked to a SQLite database 'shorturl.db'.
engine = create_engine('sqlite:///shorturl.db')
# Create all tables in the engine. This is equivalent to 'Create Table' in raw SQL.
Base.metadata.create_all(engine)
Creating and Managing Sessions
To interact with our database, we need to create a session:
Session = sessionmaker(bind=engine)
session = Session()
With this session, you can now add, delete, and query objects in your database.
Adding New URLs
Let’s define a function to add a new URL with a unique shortened code to our database:
def add_url(original_url, short_code):
new_url = ShortenedUrl(original_url=original_url, short_code=short_code)
session.add(new_url)
session.commit()
Now, you can call add_url()
with the original URL and a short code that uniquely identifies the particular URL.
Retrieving and Redirecting URLs
The next step is to retrieve the original URL from the short code:
def get_original_url(short_code):
return session.query(ShortenedUrl)
.filter(ShortenedUrl.short_code == short_code)
.first()
This function will enable us to redirect users to the original URLs when the shortened URL is accessed.
Advanced Features
Besides basic URL addition and retrieval, a pragmatic short URL service may need advanced features like URL hit tracking, deletion after a set expiration time, and more.
Tracking Hits
class UrlHit(Base):
__tablename__ = 'url_hits'
id = Column(Integer, primary_key=True)
short_url_id = Column(Integer, ForeignKey('shortened_urls.id'))
accessed_at = Column(DateTime, default=datetime.utcnow)
Base.metadata.create_all(engine) # Repeat this if you've defined new models after the initial run.
Storing hits to a URL allows you to track the number of times a shortened URL is accessed over time. Use the following function to record a URL hit:
def log_url_hit(short_url_id):
hit = UrlHit(short_url_id=short_url_id)
session.add(hit)
session.commit()
Expiration and Cleanup
To set up expiration for URLs, you can add an additional field to the ShortenedUrl
model:
class ShortenedUrl(Base):
# ...
expires_at = Column(DateTime)
# Add a method to check if the URL is expired
def is_expired(self):
return datetime.utcnow() > self.expires_at if self.expires_at else False
You can now write a scheduler that regularly checks for expired URLs and deletes them:
def delete_expired_urls():
session.query(ShortenedUrl)
.filter(ShortenedUrl.expires_at < datetime.utcnow())
.delete(synchronize_session=False)
session.commit()
Putting it All Together
With these components in place, you can now build a complete shortened URL service. Each piece can be expanded upon to include more functionality as required by your application needs.
Conclusion
SQLAlchemy is a flexible ORM that enables Python developers to produce database-interacting code efficiently and in an object-oriented manner. By following this tutorial, you’ve learned how to design a robust database for a URL shortening service using the latest SQLAlchemy practices.