<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alex Rivers</title>
    <description>The latest articles on DEV Community by Alex Rivers (@alexrivers).</description>
    <link>https://dev.to/alexrivers</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2928732%2F39d3d2c4-e158-491b-beca-a4a859e5cbac.png</url>
      <title>DEV Community: Alex Rivers</title>
      <link>https://dev.to/alexrivers</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexrivers"/>
    <language>en</language>
    <item>
      <title>Supercharge Your PostgreSQL Queries with Materialized Views! 🚀</title>
      <dc:creator>Alex Rivers</dc:creator>
      <pubDate>Sat, 06 Sep 2025 14:43:41 +0000</pubDate>
      <link>https://dev.to/alexrivers/supercharge-your-postgresql-queries-with-materialized-views-4g02</link>
      <guid>https://dev.to/alexrivers/supercharge-your-postgresql-queries-with-materialized-views-4g02</guid>
      <description>&lt;p&gt;Are your complex SELECT queries with multiple JOINs and GROUP BY clauses slowing down your application? If you're frequently running expensive calculations on data that doesn't change every second, a materialized view might be your new best friend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a Materialized View?&lt;/strong&gt;&lt;br&gt;
Think of a standard view as a saved query that runs every time you access it. It's always fresh, but if the underlying query is slow, accessing the view will also be slow.&lt;/p&gt;

&lt;p&gt;A materialized view, on the other hand, is like a snapshot. It executes a query and stores the results physically on disk, just like a regular table. When you query the materialized view, you're just reading these pre-computed results, which is incredibly fast! ⚡&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When Should You Use One?&lt;/strong&gt;&lt;br&gt;
Materialized views are perfect for:&lt;/p&gt;

&lt;p&gt;Dashboards &amp;amp; Reporting: When you need to display aggregated data (e.g., daily sales totals, monthly user signups) and a slight delay is acceptable.&lt;/p&gt;

&lt;p&gt;Complex Aggregations: For queries that involve heavy calculations, multiple joins, or large datasets that are costly to run repeatedly.&lt;/p&gt;

&lt;p&gt;Data Warehousing: Summarizing large tables into more manageable forms for analysis.&lt;/p&gt;

&lt;p&gt;The key is that the underlying data doesn't need to be real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Quick Example&lt;/strong&gt;&lt;br&gt;
Let's say you have a complex query to calculate total sales per product.&lt;/p&gt;

&lt;p&gt;1) Create the Materialized View:&lt;br&gt;
You define it just like a regular table or view, using your slow query.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CREATE MATERIALIZED VIEW daily_sales_summary AS&lt;br&gt;
SELECT&lt;br&gt;
    p.product_name,&lt;br&gt;
    SUM(s.quantity * s.price) AS total_revenue,&lt;br&gt;
    DATE(s.sale_date) AS sale_day&lt;br&gt;
FROM sales s&lt;br&gt;
JOIN products p ON s.product_id = p.id&lt;br&gt;
GROUP BY p.product_name, sale_day;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2) Query It (The Fast Part!):&lt;br&gt;
Now, querying this data is as simple and fast as selecting from a table.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM daily_sales_summary WHERE sale_day = '2025-09-05';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3) Keep It Fresh:&lt;br&gt;
The one catch is that the data can become stale. You need to explicitly tell PostgreSQL to update it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;REFRESH MATERIALIZED VIEW daily_sales_summary;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can schedule this REFRESH command to run periodically (e.g., every hour or overnight) using a cron job or a tool like pg_cron.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Trade-Offs&lt;/strong&gt;&lt;br&gt;
Stale Data: The view is only as fresh as its last REFRESH.&lt;/p&gt;

&lt;p&gt;Storage Space: Since the results are stored on disk, it consumes storage.&lt;/p&gt;

&lt;p&gt;Refresh Time: The refresh process itself can be resource-intensive, as it has to re-run the original complex query.&lt;/p&gt;

&lt;p&gt;By understanding these trade-offs, you can leverage materialized views to significantly boost your database's performance for read-heavy workloads.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Top 3 PostgreSQL Performance Issues: Diagnosis and Proven Solutions</title>
      <dc:creator>Alex Rivers</dc:creator>
      <pubDate>Sun, 16 Mar 2025 18:29:44 +0000</pubDate>
      <link>https://dev.to/alexrivers/top-3-postgresql-performance-issues-diagnosis-and-proven-solutions-1139</link>
      <guid>https://dev.to/alexrivers/top-3-postgresql-performance-issues-diagnosis-and-proven-solutions-1139</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. Slow Queries Due to Lack of Indexing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The absence of appropriate indexes is a primary culprit for slow query execution in PostgreSQL. When a query requires filtering or sorting data, PostgreSQL might resort to a full table scan (also known as a sequential scan) if the relevant columns lack indexes. This involves examining every row in the table, which becomes increasingly time-consuming and resource-intensive as the table size grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad Table Design Example (Continued):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Frequent query without an index:&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test@example.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EXPLAIN Output (before adding index):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUERY PLAN
-------------------------------------------------
 Seq Scan on users  (cost=0.00..16.50 rows=1 width=36)
   Filter: ((email)::text = 'test@example.com'::text)
(2 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Diagnosis:&lt;/strong&gt; The &lt;code&gt;EXPLAIN&lt;/code&gt; output clearly indicates a &lt;code&gt;Seq Scan&lt;/code&gt; (Sequential Scan) on the &lt;code&gt;users&lt;/code&gt; table. This signifies that PostgreSQL is examining every row in the table to find the matching email address. The &lt;code&gt;cost&lt;/code&gt; estimate also provides an indication of the query's potential resource consumption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proven Solution: Adding an Index&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To optimize the query, we can create an index on the &lt;code&gt;email&lt;/code&gt; column. A B-tree index is the most common and generally effective type of index for equality and range comparisons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EXPLAIN Output (after adding index):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;QUERY PLAN
-------------------------------------------------------------------
 Index Scan using idx_users_email on users  (cost=0.14..8.16 rows=1 width=36)
   Index Cond: ((email)::text = 'test@example.com'::text)
(2 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; After adding the index, the &lt;code&gt;EXPLAIN&lt;/code&gt; output now shows an &lt;code&gt;Index Scan&lt;/code&gt; using the newly created &lt;code&gt;idx_users_email&lt;/code&gt; index. The &lt;code&gt;Index Cond&lt;/code&gt; indicates that the index is being used to directly locate the relevant rows based on the email address. Notice the significantly lower &lt;code&gt;cost&lt;/code&gt; estimate, indicating a more efficient query plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further Considerations for Indexing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Index Types:&lt;/strong&gt; PostgreSQL offers various index types (e.g., B-tree, Hash, GIN, GIST, BRIN) suitable for different data types and query patterns. Choose the appropriate index type based on your specific needs. For example, GIN indexes are excellent for full-text search or indexing array and JSONB data, while GIST indexes are often used for spatial data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composite Indexes:&lt;/strong&gt; If you frequently query on multiple columns together, consider creating a composite index that includes all those columns in the appropriate order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-indexing:&lt;/strong&gt; While indexes improve read performance for certain queries, they can slow down write operations (INSERT, UPDATE, DELETE) as the index also needs to be updated. Avoid creating unnecessary indexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identifying Missing Indexes:&lt;/strong&gt; Tools like &lt;code&gt;pg_stat_statements&lt;/code&gt; (an extension that tracks query execution statistics) can help identify frequently executed queries that could benefit from indexing. Analyzing slow query logs can also pinpoint queries taking excessive time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Bloat and Inefficient Vacuuming&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Over time, PostgreSQL tables and indexes can accumulate "bloat." Bloat refers to dead tuples (rows that have been logically deleted or updated but are still physically present in the database files). This unused space can lead to increased storage consumption, slower sequential scans, and less efficient index operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring Table and Index Sizes:&lt;/strong&gt; Regularly monitor the size of your tables and indexes. A sudden or unexpected increase might indicate bloat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;pg_stat_all_tables&lt;/code&gt; and &lt;code&gt;pg_stat_all_indexes&lt;/code&gt;:&lt;/strong&gt; These system views provide statistics about table and index activity, including the number of dead tuples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialized Tools and Queries:&lt;/strong&gt; Several community-developed scripts and extensions (like &lt;code&gt;pgstattuple&lt;/code&gt;) can provide more detailed information about bloat levels in tables and indexes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Proven Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regular &lt;code&gt;VACUUM&lt;/code&gt;:&lt;/strong&gt; The &lt;code&gt;VACUUM&lt;/code&gt; command reclaims storage occupied by dead tuples. A regular &lt;code&gt;VACUUM&lt;/code&gt; operation is essential for maintaining database performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;AUTOVACUUM&lt;/code&gt;:&lt;/strong&gt; PostgreSQL has an &lt;code&gt;autovacuum&lt;/code&gt; daemon that automatically performs &lt;code&gt;VACUUM&lt;/code&gt; and &lt;code&gt;ANALYZE&lt;/code&gt; operations in the background. Ensure that &lt;code&gt;autovacuum&lt;/code&gt; is enabled and properly configured. Adjusting parameters like &lt;code&gt;autovacuum_vacuum_threshold&lt;/code&gt; and &lt;code&gt;autovacuum_vacuum_scale_factor&lt;/code&gt; might be necessary based on your workload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;VACUUM FULL&lt;/code&gt; (Use with Caution):&lt;/strong&gt; The &lt;code&gt;VACUUM FULL&lt;/code&gt; command rewrites the entire table, reclaiming all dead space and potentially reducing the table size on disk. However, it requires an exclusive lock on the table, making it unavailable for other operations. It should be used sparingly and during maintenance windows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pg_repack&lt;/code&gt;:&lt;/strong&gt; This is an online, non-blocking full table rewrite solution that can be used to eliminate bloat without requiring exclusive locks. It's a more advanced option for critical production environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Inefficient Queries Beyond Indexing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even with proper indexing, some queries can still perform poorly due to their structure and the operations they perform. Inefficient query patterns can put unnecessary load on the database server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;:&lt;/strong&gt; Unlike &lt;code&gt;EXPLAIN&lt;/code&gt;, &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; actually executes the query and provides detailed information about the execution time of each step in the query plan. This is invaluable for identifying bottlenecks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slow Query Logs:&lt;/strong&gt; Configure PostgreSQL to log queries that take longer than a specified threshold. Analyzing these logs can reveal patterns of inefficient queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;pg_stat_statements&lt;/code&gt;:&lt;/strong&gt; This extension provides statistics on the execution time and resource usage of all executed SQL statements, helping to identify the most time-consuming queries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Proven Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rewriting Queries:&lt;/strong&gt; Often, a poorly performing query can be significantly improved by rewriting it. This might involve:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Avoiding &lt;code&gt;SELECT *&lt;/code&gt;:&lt;/strong&gt; Only select the columns you actually need. Retrieving unnecessary data increases I/O and network traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimizing &lt;code&gt;WHERE&lt;/code&gt; clauses:&lt;/strong&gt; Ensure that your &lt;code&gt;WHERE&lt;/code&gt; clauses are selective and use indexed columns effectively. Avoid using functions on indexed columns in the &lt;code&gt;WHERE&lt;/code&gt; clause (e.g., &lt;code&gt;WHERE lower(email) = ...&lt;/code&gt;) as it might prevent index usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Joins:&lt;/strong&gt; Understand the different types of joins (INNER, LEFT, RIGHT, FULL) and choose the most appropriate one for your needs. Ensure that join conditions use indexed columns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limiting Results:&lt;/strong&gt; Use &lt;code&gt;LIMIT&lt;/code&gt; and &lt;code&gt;OFFSET&lt;/code&gt; clauses when fetching only a subset of rows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using Appropriate Functions:&lt;/strong&gt; Leverage built-in PostgreSQL functions for specific tasks instead of performing complex logic in your application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Considering Materialized Views:&lt;/strong&gt; For frequently executed complex queries with relatively static underlying data, consider using materialized views to pre-compute and store the results.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Analyzing Query Plans:&lt;/strong&gt; Carefully examine the output of &lt;code&gt;EXPLAIN&lt;/code&gt; and &lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt; to understand how PostgreSQL is executing your queries and identify potential areas for optimization. Look for operations like &lt;code&gt;Seq Scan&lt;/code&gt; on large tables when an index scan is expected, or inefficient join algorithms like &lt;code&gt;Merge Join&lt;/code&gt; when a &lt;code&gt;Hash Join&lt;/code&gt; might be more appropriate.&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Partitioning:&lt;/strong&gt; For very large tables, consider partitioning them into smaller, more manageable chunks. This can improve query performance by allowing PostgreSQL to only scan the relevant partitions.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Want to learn more? Check out these resources:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.somethingsblog.com/2025/03/16/top-9-postgresql-performance-issues-and-how-to-fix-them/" rel="noopener noreferrer"&gt;https://www.somethingsblog.com/2025/03/16/top-9-postgresql-performance-issues-and-how-to-fix-them/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Unlocking the Power of Global Variables in Python</title>
      <dc:creator>Alex Rivers</dc:creator>
      <pubDate>Sat, 15 Mar 2025 03:40:33 +0000</pubDate>
      <link>https://dev.to/alexrivers/unlocking-the-power-of-global-variables-in-python-2pim</link>
      <guid>https://dev.to/alexrivers/unlocking-the-power-of-global-variables-in-python-2pim</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Basics of Variable Scope&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Python, a variable's scope determines its visibility and accessibility within a program. Understanding variable scope is crucial to mastering the art of working with global variables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessing Global Variables from Within Functions&lt;/strong&gt;&lt;br&gt;
Imagine you have a global variable, and you want to access it from inside a function. Let's see how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c = 1
def add():
    print(c)
add()  # Output: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we've successfully accessed the global variable c from within the add() function. However, if we try to modify c from inside the function, we'll run into trouble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c = 1
def add():
    c = c + 2
    print(c)
add()  # Error!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason for this error is that Python treats c as a local variable by default, and we can't modify a global variable from within a function without explicitly declaring it as global.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: Using the Global Keyword&lt;/strong&gt;&lt;br&gt;
This is where the global keyword comes to the rescue. By using global, we can modify a global variable from within a function. Let's see how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;c = 1
def add():
    global c
    c = c + 2
    print(c)
add()  # Output: 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we've successfully modified the global variable c from within the add() function using the global keyword.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Rules of the Global Keyword&lt;/strong&gt;&lt;br&gt;
Now that we've seen the power of the global keyword, let's explore its rules:&lt;/p&gt;

&lt;p&gt;Local by Default: When you create a variable inside a function, it's local by default.&lt;br&gt;
Global by Default: When you define a variable outside of a function, it's global by default – no need to use the global keyword.&lt;br&gt;
Modify with Care: Use the global keyword to modify a global variable inside a function.&lt;br&gt;
No Effect Outside: Using the global keyword outside a function has no effect.&lt;br&gt;
Working with Nested Functions&lt;/p&gt;

&lt;p&gt;But what happens when we have nested functions? How do we access and modify global variables in such scenarios? Stay tuned for our next article, where we'll explore the intricacies of global variables in nested functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further Reading&lt;/strong&gt;&lt;br&gt;
Want to learn more? Check out these resources:&lt;br&gt;
&lt;a href="https://www.somethingsblog.com/2024/10/18/mastering-python-global-variables-a-beginners-guidethis-title-is-short-engaging-and-optimized-for-seo-targeting-keywords-like-python-global-variables-and-beginners-guide/" rel="noopener noreferrer"&gt;https://www.somethingsblog.com/2024/10/18/mastering-python-global-variables-a-beginners-guidethis-title-is-short-engaging-and-optimized-for-seo-targeting-keywords-like-python-global-variables-and-beginners-guide&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
    </item>
    <item>
      <title>Unlock Web Magic: Build Your First Flask App (Beginner-Friendly Guide)</title>
      <dc:creator>Alex Rivers</dc:creator>
      <pubDate>Mon, 10 Mar 2025 15:45:01 +0000</pubDate>
      <link>https://dev.to/alexrivers/unlock-web-magic-build-your-first-flask-app-beginner-friendly-guide-n1g</link>
      <guid>https://dev.to/alexrivers/unlock-web-magic-build-your-first-flask-app-beginner-friendly-guide-n1g</guid>
      <description>&lt;p&gt;Hey there, aspiring web developers! Ready to dive into the exciting world of web application development with Python?  You've come to the right place! Today, we're going to demystify web frameworks and walk you through building your very own Flask application – a lightweight yet powerful tool for crafting web experiences.&lt;/p&gt;

&lt;p&gt;If you've ever felt intimidated by the complexities of web development, fear not! Flask is designed to be &lt;strong&gt;beginner-friendly&lt;/strong&gt;, &lt;strong&gt;flexible&lt;/strong&gt;, and incredibly &lt;strong&gt;Pythonic&lt;/strong&gt;. Think of it as a nimble toolkit that gives you just what you need to build web apps, without unnecessary bloat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Flask?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we jump into code, let's quickly touch upon why Flask is a fantastic choice, especially for beginners:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Microframework Magic:&lt;/strong&gt; Flask is a "microframework," meaning it provides the essential tools without imposing too many pre-set structures. This gives you more control and flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pythonic Simplicity:&lt;/strong&gt;  Built with Python principles in mind, Flask feels intuitive for Python developers.  You'll write clean, readable code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensibility:&lt;/strong&gt;  While lean at its core, Flask is highly extensible. You can easily add features as you need them using extensions for things like databases, authentication, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Large Community &amp;amp; Resources:&lt;/strong&gt;  Flask has a thriving community and plenty of online resources, making it easy to find help and learn more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ready to build? Let's get started!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what we'll cover in this step-by-step guide:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Setting up your environment:&lt;/strong&gt;  Getting your computer ready for Flask development.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Creating your first Flask app:&lt;/strong&gt; Writing the basic code structure.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Defining a route and view function:&lt;/strong&gt;  Making your app respond to web requests.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Running your Flask app:&lt;/strong&gt;  Launching your creation and seeing it in action!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Setting up your Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we start coding, we need to make sure you have the necessary tools installed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;  You'll need Python installed on your system. If you don't have it already, download the latest version from &lt;a href="https://www.google.com/url?sa=E&amp;amp;source=gmail&amp;amp;q=https://www.python.org/" rel="noopener noreferrer"&gt;python.org&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pip (Package Installer for Python):&lt;/strong&gt;  &lt;code&gt;pip&lt;/code&gt; usually comes bundled with Python installations. We'll use it to install Flask.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Virtual Environment (Recommended):&lt;/strong&gt;  While not strictly mandatory for this simple example, using a virtual environment is &lt;em&gt;highly recommended&lt;/em&gt; for any Python project. It isolates your project dependencies, preventing conflicts.&lt;/p&gt;

&lt;p&gt;Open your terminal or command prompt and navigate to the directory where you want to create your project. Then, create a virtual environment (we'll call it &lt;code&gt;venv&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For macOS/Linux&lt;/span&gt;
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv

&lt;span class="c"&gt;# For Windows&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Activate the virtual environment:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For macOS/Linux&lt;/span&gt;
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate

&lt;span class="c"&gt;# For Windows&lt;/span&gt;
venv&lt;span class="se"&gt;\S&lt;/span&gt;cripts&lt;span class="se"&gt;\a&lt;/span&gt;ctivate
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;You should see &lt;code&gt;(venv)&lt;/code&gt; at the beginning of your terminal prompt, indicating that the virtual environment is active.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Flask:&lt;/strong&gt;  Now, with your virtual environment activated, use &lt;code&gt;pip&lt;/code&gt; to install Flask:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;Flask
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;That's it for setup! You're ready to start coding.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Creating Your First Flask App (app.py)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's create a file named &lt;code&gt;app.py&lt;/code&gt; (you can name it something else if you prefer, but &lt;code&gt;app.py&lt;/code&gt; is a common convention).  Open your favorite text editor or code editor and paste the following code into &lt;code&gt;app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello_world&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Hello, World!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down what's happening in this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;from flask import Flask&lt;/code&gt;:&lt;/strong&gt; This line imports the &lt;code&gt;Flask&lt;/code&gt; class from the &lt;code&gt;flask&lt;/code&gt; library. We need this class to create our Flask application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;app = Flask(__name__)&lt;/code&gt;:&lt;/strong&gt; This line creates an instance of the &lt;code&gt;Flask&lt;/code&gt; class and assigns it to the variable &lt;code&gt;app&lt;/code&gt;.  &lt;code&gt;__name__&lt;/code&gt; is a special Python variable that refers to the name of the current module.  Flask uses this to determine the root path of your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;@app.route('/')&lt;/code&gt;:&lt;/strong&gt; This is a &lt;strong&gt;decorator&lt;/strong&gt;. Decorators in Python are a way to modify or extend the behavior of functions.  &lt;code&gt;@app.route('/')&lt;/code&gt; tells Flask that the function immediately following it (&lt;code&gt;hello_world()&lt;/code&gt;) should be executed when a user visits the root URL of your application (i.e., &lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;def hello_world():&lt;/code&gt;:&lt;/strong&gt; This is our &lt;strong&gt;view function&lt;/strong&gt;. It's a function that handles requests to a specific route. In this case, when a user visits the root URL (&lt;code&gt;/&lt;/code&gt;), Flask will call this function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;return 'Hello, World!'&lt;/code&gt;:&lt;/strong&gt;  This line specifies what the &lt;code&gt;hello_world()&lt;/code&gt; function should return. In this case, it returns the string "Hello, World!".  Flask will automatically interpret this string as the response to be sent back to the user's browser.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;if __name__ == '__main__':&lt;/code&gt;:&lt;/strong&gt; This is a standard Python construct.  It ensures that the code inside the &lt;code&gt;if&lt;/code&gt; block is only executed when you run the &lt;code&gt;app.py&lt;/code&gt; file directly (not when it's imported as a module).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;app.run(debug=True)&lt;/code&gt;:&lt;/strong&gt; This line starts the Flask development server.  &lt;code&gt;debug=True&lt;/code&gt; enables debug mode, which is helpful during development because it provides automatic reloading when you make code changes and displays helpful error messages. &lt;strong&gt;Remember to disable &lt;code&gt;debug=True&lt;/code&gt; when deploying your application to production!&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Running Your Flask App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now for the exciting part – running your app!  Open your terminal or command prompt in the same directory where you saved &lt;code&gt;app.py&lt;/code&gt;.  Make sure your virtual environment is still activated. Then, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; * Environment: development
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 123-456-789 (This will be different for you)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means your Flask development server is running!  Open your web browser and go to the address shown in the output, usually &lt;strong&gt;&lt;code&gt;http://127.0.0.1:5000/&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎉 Congratulations! 🎉&lt;/strong&gt; You should see the glorious words:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hello, World!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You've just built and run your first Flask web application!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Exploring and Expanding&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Hello, World!" is just the beginning. Let's briefly touch on how you can expand your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;More Routes:&lt;/strong&gt; You can define more routes using the &lt;code&gt;@app.route()&lt;/code&gt; decorator to handle different URLs. For example:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/about&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;about_page&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;This is the about page.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Now, visiting &lt;code&gt;http://127.0.0.1:5000/about&lt;/code&gt; will display "This is the about page."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Dynamic Routes:&lt;/strong&gt; You can create routes with variables:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/user/&amp;lt;username&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_user_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;User profile for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Visiting &lt;code&gt;http://127.0.0.1:5000/user/JohnDoe&lt;/code&gt; will display "User profile for: JohnDoe".&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTML Templates:&lt;/strong&gt; To create more visually appealing web pages, you'll want to use HTML templates. Flask uses Jinja2 templating engine.  You'll create HTML files and render them from your view functions.  This is a crucial step for building real-world web applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Static Files:&lt;/strong&gt;  You can serve static files like CSS, JavaScript, and images.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Databases:&lt;/strong&gt;  Flask integrates seamlessly with databases to store and retrieve data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Forms:&lt;/strong&gt;  Handle user input with forms.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where to Go Next?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This blog post has just scratched the surface of what you can do with Flask.  Here are some excellent resources to continue your learning journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flask Tutorial:&lt;/strong&gt; &lt;a href="https://www.somethingsblog.com/2023/08/30/how-to-create-a-python-web-app-with-authentication-and-an-api/" rel="noopener noreferrer"&gt;https://www.somethingsblog.com/2023/08/30/how-to-create-a-python-web-app-with-authentication-and-an-api/&lt;/a&gt; - A fantastic, in-depth tutorial that guides you through building a more complex application.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flask</category>
      <category>python</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
