<?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: Mee Mee Alainmar</title>
    <description>The latest articles on DEV Community by Mee Mee Alainmar (@meemeealm).</description>
    <link>https://dev.to/meemeealm</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%2F3781051%2F63d19e1d-140d-4128-bf37-731e39c91de4.jpg</url>
      <title>DEV Community: Mee Mee Alainmar</title>
      <link>https://dev.to/meemeealm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/meemeealm"/>
    <language>en</language>
    <item>
      <title>Simple Queue Can Save Your Pipeline: DuckDB + Python</title>
      <dc:creator>Mee Mee Alainmar</dc:creator>
      <pubDate>Wed, 08 Apr 2026 15:20:43 +0000</pubDate>
      <link>https://dev.to/meemeealm/simple-queue-can-save-your-pipeline-duckdb-python-1hn0</link>
      <guid>https://dev.to/meemeealm/simple-queue-can-save-your-pipeline-duckdb-python-1hn0</guid>
      <description>&lt;p&gt;If you’ve ever tried to shove millions of rows into a database, you know the pain, slow inserts, blocked threads, and that sinking feeling when your pipeline just can’t keep up. &lt;/p&gt;

&lt;p&gt;I recently worked on a minimal pipeline design that tackles this problem head-on, and I think it’s worth sharing, especially if you’re building a bronze layer for data lake.&lt;/p&gt;

&lt;p&gt;For small to medium scale workloads (think tens of millions of rows), this pipeline is enough. It’s simple, easy to maintain, and doesn’t require spinning up distributed infrastructure. DuckDB is surprisingly capable here.&lt;/p&gt;

&lt;p&gt;You can access the repo here: &lt;a href="https://github.com/meemeealm/Multithreaded-Ingestion-Pipeline.git" rel="noopener noreferrer"&gt;https://github.com/meemeealm/Multithreaded-Ingestion-Pipeline.git&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Idea&lt;/strong&gt;&lt;br&gt;
The pipeline is built around a &lt;strong&gt;producer-consumer model&lt;/strong&gt;. Instead of one big monolithic process, we split responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Producer (Shredder Thread): Reads Parquet rows, batches them, and pushes them into a queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Queue (Thread-safe buffer): Acts as the middleman. It smooths out the flow and prevents the producer from overwhelming the consumers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consumers (Workers): Multiple threads pull from the queue, cast types, batch inserts, and push data into DuckDB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DuckDB: Landing zone. Everything fans in here, into a raw_data table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So for a nice fan-out → fan-in pattern: one producer, many workers (3 workers in example), one database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1j2xj7ghdixkzr2nc531.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1j2xj7ghdixkzr2nc531.png" alt="Parallel Ingestion Pipeline" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Queue Pattern
&lt;/h2&gt;

&lt;p&gt;The critical part of this pipeline is queue. It also provides backpressure control, meaning, if workers are slower, the queue absorbs the imbalance.&lt;/p&gt;

&lt;p&gt;The producer fills the queue with batches of rows, but it’s the workers that show the queue pattern in action — they keep pulling jobs out, processing them, and marking them done. This is the classic producer–consumer setup.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;db_ingestor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;worker_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;job_queue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shared_con&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Each worker gets its own cursor from the shared connection
&lt;/span&gt;        &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shared_con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&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;[Worker - &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;worker_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] Ready and waiting for data...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;job_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Pull next job from the queue
&lt;/span&gt;            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Poison pill → stop signal
&lt;/span&gt;                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                        &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executemany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO raw_data VALUES (?, ?, ?)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;

                &lt;span class="c1"&gt;# Cast row values into proper types
&lt;/span&gt;                &lt;span class="n"&gt;clean_row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; 
                    &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; 
                    &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;category&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clean_row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Insert batch when it reaches the limit
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executemany&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO raw_data VALUES (?, ?, ?)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="n"&gt;batch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

            &lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Mark the job as done so the queue knows it’s processed
&lt;/span&gt;                &lt;span class="n"&gt;job_queue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task_done&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;Why This Works for Bronze Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The bronze layer is all about raw ingestion. Here, fancy transformations is not required yet — the most critical job is to just get the data in reliably. &lt;/p&gt;

&lt;p&gt;This design is good for -&lt;br&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt;: Multiple workers keep inserts flowing without bottlenecks.&lt;br&gt;
&lt;strong&gt;Decoupling&lt;/strong&gt;: Producer and consumers don’t block each other. If one side slows down, the queue absorbs the shock.&lt;br&gt;
&lt;strong&gt;Batching&lt;/strong&gt;: Both reads and writes are batched, which makes inserts way faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Python GIL&lt;/strong&gt;: If your workers are CPU-heavy, threading won’t scale in long run. Multiprocessing or native extensions might be needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Single-node DB&lt;/strong&gt;: DuckDB is designed to run on a single machine, so if your workload grows beyond what one node can handle, you’ll eventually need to switch to a distributed system&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error handling&lt;/strong&gt;: In bronze layer, usually it doesn’t demand perfection, but you’ll still want retries and logging (which is not in this pipeline). &lt;/p&gt;

</description>
      <category>python</category>
      <category>database</category>
      <category>dataengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>From Data to Deployment: My Journey in the Google Cloud Gen AI Academy APAC 🚀</title>
      <dc:creator>Mee Mee Alainmar</dc:creator>
      <pubDate>Tue, 17 Mar 2026 13:01:52 +0000</pubDate>
      <link>https://dev.to/meemeealm/from-data-to-deployment-my-journey-in-the-google-cloud-gen-ai-academy-apac-oj1</link>
      <guid>https://dev.to/meemeealm/from-data-to-deployment-my-journey-in-the-google-cloud-gen-ai-academy-apac-oj1</guid>
      <description>&lt;p&gt;I recently joined the Gen AI Academy APAC, powered by Google Cloud and &lt;a href="https://hack2skill.com/" rel="noopener noreferrer"&gt;Hack2Skill&lt;/a&gt;, and it has been a fruitful experience for me.&lt;br&gt;
So if you’re in the APAC region and looking to move beyond Jupyter Notebooks into production-grade AI in Google Cloud Environment, here’s why this program should be on your radar.&lt;/p&gt;




&lt;p&gt;It’s a zero-cost, challenge-based program designed to upskill developers across the Asia-Pacific region. Unlike a standard video course, this is a "Build-First" environment. We aren't just learning theory; we are using Vertex AI, Cloud Run and AI-ready databases to solve real-world problems.&lt;/p&gt;




&lt;p&gt;For practicing codelab session, the program provides the credits to practice the labs smoothly. &lt;/p&gt;

&lt;p&gt;There are three tracks participants can pick: one or all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Track 1&lt;/strong&gt;- Build and deploy AI agents using Gemini, ADK, and Cloud Run&lt;br&gt;
&lt;strong&gt;Track 2&lt;/strong&gt; - Connect AI agents to real-world data and tools using Model Context Protocol (MCP)&lt;br&gt;
&lt;strong&gt;Track 3&lt;/strong&gt; - Build AI-powered applications using AI-ready databases like AlloyDB&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kwzbzd5hccawoij6fit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1kwzbzd5hccawoij6fit.png" alt="genai academy timeline" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FAQs about this program: &lt;a href="https://docs.google.com/document/d/1XtCFsoUUIxzKlCALkCQ74jPlt5Kp_0te7i7Ie-xhg_k/edit?tab=t.0" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Register here: &lt;a href="https://vision.hack2skill.com/event/apac-genaiacademy?utm_source=hack2skill&amp;amp;utm_medium=homepage" rel="noopener noreferrer"&gt;Hack2Skill Vision Portal&lt;/a&gt;&lt;/p&gt;

</description>
      <category>google</category>
      <category>ai</category>
      <category>cloud</category>
    </item>
    <item>
      <title>From My Kitchen to Yours: I Built a Food Swap Board for My Neighborhood using streamlit and sqlite3</title>
      <dc:creator>Mee Mee Alainmar</dc:creator>
      <pubDate>Sun, 01 Mar 2026 22:23:31 +0000</pubDate>
      <link>https://dev.to/meemeealm/from-my-kitchen-to-yours-i-built-a-food-swap-board-for-my-neighborhood-23ej</link>
      <guid>https://dev.to/meemeealm/from-my-kitchen-to-yours-i-built-a-food-swap-board-for-my-neighborhood-23ej</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💁🏽‍♀️ The Community
&lt;/h2&gt;

&lt;p&gt;In my part of the world (Southeast Asia), we have a beautiful culture of "အိမ်နီးနားချင်း", "Gotong Royong" or "Bayanihan." It’s that unwritten rule that if your mango tree is overflowing, you don’t let the fruit rot, you pass it over the fence to your neighbor.  &lt;/p&gt;

&lt;p&gt;This culture is still alive in some parts of rural areas. However, in our modern, fast-paced neighborhoods, we’ve lost that "over the fence" connection. I built this app to bring that village-style sharing into the digital age.&lt;/p&gt;

&lt;h2&gt;
  
  
  🥔 What I Built
&lt;/h2&gt;

&lt;p&gt;NextDoor is a lightweight, real-time bulletin board for food sharing. It’s a &lt;strong&gt;"zero-waste" tool&lt;/strong&gt; that lets neighbors post surplus garden harvests, pantry extras, or home-cooked meals.&lt;/p&gt;

&lt;p&gt;The Goal is to make sure no wasted food happens in my home or in our neighborhood. And there is also direct-to-WhatsApp integration that skips the "official" sign-up friction and gets neighbors talking instantly.&lt;/p&gt;




&lt;h3&gt;
  
  
  🏘️ Community-First Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regional Pantry Sharing&lt;/strong&gt; Specifically designed for the South East Asian kitchen. Whether it's extra &lt;em&gt;Kangkong&lt;/em&gt; from the garden, or fresh &lt;em&gt;Lime&lt;/em&gt;, the board is built to showcase the flavors of our local community.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliable "Always-On" Board&lt;/strong&gt; Unlike temporary chat groups where messages get buried, this digital board keeps a permanent record of what’s available. The post stays visible until the item is gone, ensuring nothing in the neighborhood goes to waste.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant WhatsApp Coordination&lt;/strong&gt; One tap on the green message button opens a direct chat with the owner, complete with a pre-written message asking if the item is still available. It’s the fastest way to say "I'm coming over!"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neighbor-Wide "Claim" System&lt;/strong&gt; When a neighbor clicks "Claim," the item is instantly marked as &lt;strong&gt;Reserved&lt;/strong&gt; for everyone viewing the board. This prevents three different people from showing up at your door for the same bag of mangoes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Pantry Discovery&lt;/strong&gt; Looking for something specific like &lt;em&gt;Eggs&lt;/em&gt; or &lt;em&gt;Basil&lt;/em&gt;? The search and category filters let you skip the scroll and find exactly what you need in seconds, whether it’s a cooked meal or garden herbs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean, Color-Coded Interface&lt;/strong&gt; The board is designed for clarity. Available items are bright and clear, while reserved items are neatly crossed out. The color-coded buttons make it obvious how to reach out or how to grab a spare portion of food.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effortless Posting&lt;/strong&gt; A simple sidebar form allows anyone to list an item in seconds. Just type what you have, how much is available, and your contact info—the board handles the rest, keeping the neighborhood fed and connected.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🌍 Community Impact: Why this Matters
&lt;/h3&gt;

&lt;p&gt;Building a neighborhood food swap isn't just about sharing, it's about creating a sustainable ecosystem right at your doorstep. Here is how &lt;strong&gt;NextDoor&lt;/strong&gt; transforms our local community:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Waste Neighborhoods&lt;/strong&gt;
Every bunch of &lt;em&gt;Kangkong&lt;/em&gt; or bowl of &lt;em&gt;Pancit&lt;/em&gt; shared is one less item ending up in a landfill. By connecting neighbors with surplus food to those who need it, we turn potential waste into shared meals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Food Security at the Hyper-Local Level&lt;/strong&gt;
Inflation and rising food costs affect us all. NextDoor provides a safety net where neighbors can support one another, ensuring that fresh produce and home-cooked meals remain accessible within the community.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strengthening Social Bonds&lt;/strong&gt;
In a world of digital walls, this platform encourages real-world interaction. Meeting a neighbor at the gate to hand over fresh &lt;em&gt;Cauliflower&lt;/em&gt; builds trust and fosters a sense of belonging that traditional social media often misses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supporting Local Home-Cooks&lt;/strong&gt;
It provides a stage for home-cooks to share their passion. Whether it’s a surplus of &lt;em&gt;Ube Halaya&lt;/em&gt; or a large pot of &lt;em&gt;Curry&lt;/em&gt;, the app helps neighbors discover the culinary talents living just a few doors away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant Response for Perishables&lt;/strong&gt;
Because the app is designed for speed (with one-tap WhatsApp links), perishable items like overripe mangoes or freshly cooked rice find a home within minutes, rather than hours.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎲 Demo
&lt;/h2&gt;

&lt;p&gt;The interface is responsive, making it easy for an Uncle at the wet market or a Tita in her kitchen to post an item in seconds.&lt;/p&gt;

&lt;p&gt;

&lt;iframe src="https://player.vimeo.com/video/1169548698" width="710" height="399"&gt;
&lt;/iframe&gt;


&lt;br&gt;
Link to streamlit: &lt;br&gt;


&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://nextdoor-food-swap.streamlit.app/?embed=true" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;nextdoor-food-swap.streamlit.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  💻 Code
&lt;/h2&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/meemeealm" rel="noopener noreferrer"&gt;
        meemeealm
      &lt;/a&gt; / &lt;a href="https://github.com/meemeealm/next-door-food-swap-app" rel="noopener noreferrer"&gt;
        next-door-food-swap-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A community-driven web app built with Streamlit to share surplus food and reduce local waste.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🍎 NextDoor: Neighborhood Food Swapping App&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;A localized, community-driven web application designed to reduce food waste and strengthen neighborhood ties. This app allows residents to post extra garden harvests, pantry items, or home-cooked meals for their neighbors to claim.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📸 App Preview&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;| &lt;a rel="noopener noreferrer" href="https://github.com/meemeealm/next-door-food-swap-app/blob/main/imgs/nextdoor_home.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmeemeealm%2Fnext-door-food-swap-app%2Fraw%2Fmain%2Fimgs%2Fnextdoor_home.png" width="45%"&gt;&lt;/a&gt; | &lt;a rel="noopener noreferrer" href="https://github.com/meemeealm/next-door-food-swap-app/blob/main/imgs/nextdoor_map.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fmeemeealm%2Fnext-door-food-swap-app%2Fraw%2Fmain%2Fimgs%2Fnextdoor_map.png" width="45%"&gt;&lt;/a&gt; |&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;✨ Features&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;Localized Community Board: A neighborhood-first platform tailored for South East Asian staples—sharing everything from Adobo and Kangkong to Ube and Calamansi.&lt;/p&gt;
&lt;p&gt;Persistent SQLite Backend: Robust data management using SQL, moving beyond temporary files to ensure community postings are safely stored and easily retrievable.&lt;/p&gt;
&lt;p&gt;Intelligent Search &amp;amp; Categorization: High-performance filtering that allows neighbors to instantly sort through local produce and cooked meals by keyword or regional category.&lt;/p&gt;
&lt;p&gt;Seamless WhatsApp Coordination: Direct-to-chat integration via custom-styled API links, featuring pre-filled messages to eliminate friction between neighbors.&lt;/p&gt;
&lt;p&gt;Real-time Reservation Logic: A synchronized "Claim" system that updates the database instantly, marking items as "Reserved" across all user sessions…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/meemeealm/next-door-food-swap-app" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  🧱 How I Built
&lt;/h2&gt;

&lt;p&gt;I wanted this to be fast, free to host, and easy to use. &lt;/p&gt;

&lt;p&gt;Most neighborhood apps feel cluttered. I wanted to build a high-performance, localized "Food Swap" platform using Python, Streamlit, and SQLite. &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;🗄️ From Volatile to Persistent: SQLite Integration *&lt;/em&gt;&lt;br&gt;
By implementing a relational database (SQLite), the app now handles concurrent data more reliably. I built a dedicated Data Access Layer (database.py) to decouple the SQL logic from the UI, making the app modular and easier to scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚡ Real-Time State Management&lt;/strong&gt;&lt;br&gt;
Instead of relying solely on Streamlit's Session State, I implemented a Database-Driven State for item claiming. When a user clicks "Claim," it triggers an atomic update in the DB. This ensures the "Reserved" status persists across different browsers and server restarts—no more "phantom" items.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📱 Regional UX: WhatsApp API Integration&lt;/strong&gt;&lt;br&gt;
In South East Asia, WhatsApp is the "Operating System" for the community. I integrated a custom URL generator that deep-links to WhatsApp with pre-filled URI-encoded strings.&lt;/p&gt;

&lt;p&gt;User Flow: Click Button &amp;gt;&amp;gt;&amp;gt; Open WhatsApp &amp;gt;&amp;gt;&amp;gt; Automatic Message: "Hi [Owner], is the [Item] still available?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 Pandas-Powered Querying&lt;/strong&gt;&lt;br&gt;
To keep the search "snappy," I used Pandas to handle the filtering layer. By reading SQL queries directly into DataFrames, I can perform complex string matching and category filtering on the fly with minimal latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎨 CSS-in-Python (Scoped Styling)&lt;/strong&gt;&lt;br&gt;
Streamlit can be visually rigid, so I injected a custom CSS injection layer using unsafe_allow_html. This allowed me to override the standard component styling to create a color-coded action system:&lt;br&gt;
Brand Success: WhatsApp Green (#25D366)&lt;br&gt;
Primary Action: Claim Blue (#007BFF)&lt;br&gt;
Secondary Action: Undo Grey (#6C757D)&lt;/p&gt;

&lt;h3&gt;
  
  
  Interactive Neighborhood Map
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkuws6dirk0qdjjr5djq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flkuws6dirk0qdjjr5djq.png" alt="NextDoor Map"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a dynamic, color-coded map powered by Pydeck and Mapbox/CartoDB. Instead of scrolling through an endless list, users can instantly visualize the "Supply and Demand" of their specific street.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technical Highlights:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Color-Coded Layers&lt;/strong&gt;: Items are categorized by type (Vegetables, Cooked Meals, Fruits) with distinct RGB signatures, allowing for instant visual filtering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smart Clustering&lt;/strong&gt;: Uses a custom-calculated ViewState to automatically center the map based on the geographic mean of all active listings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Interactive Tooltips&lt;/strong&gt;: Custom HTML/CSS tooltips provide a "Quick View" of item details and quantities without leaving the map interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Faker-Powered Geospatial Data&lt;/strong&gt;: For development, a custom data_generator.py simulates realistic neighborhood distribution using GPS coordinate randomization within a 3km radius.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
      <category>python</category>
    </item>
    <item>
      <title>What are Snowflake Views? A Simple Guide for Beginners</title>
      <dc:creator>Mee Mee Alainmar</dc:creator>
      <pubDate>Tue, 24 Feb 2026 04:06:03 +0000</pubDate>
      <link>https://dev.to/meemeealm/what-are-snowflake-views-a-simple-guide-for-beginners-34p7</link>
      <guid>https://dev.to/meemeealm/what-are-snowflake-views-a-simple-guide-for-beginners-34p7</guid>
      <description>&lt;p&gt;If you’ve been learning databases and modern data warehouses like Snowflake, you’ve probably heard the word "View".It sounds technical, but it’s actually one of the coolest and easiest tools.&lt;/p&gt;

&lt;p&gt;Think of a View as a "Saved Search" or a "Virtual Window" into your data existed in database. It looks like a table, acts like a table, but it’s actually just a saved recipe for a query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what exactly is a View?&lt;/strong&gt;&lt;br&gt;
Imagine you have a giant, messy spreadsheet (a Table) with 100 columns and millions of rows. &lt;/p&gt;

&lt;p&gt;In most day, you only need to see three columns: Customer Name, Item Purchased, and Price. &lt;br&gt;
Instead of writing a long code to filter that data every single morning, you create a View.&lt;br&gt;
The View is just a "shortcut" that shows you exactly what you want to see, instantly. And the Table is where the actual data lives.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Benefits of "Views"&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s a Time-Saver. You write the complex logic in SQL Worksheet once, name it (e.g., Daily_Sales_View), and then you just call that name whenever you need it.&lt;/li&gt;
&lt;li&gt;It’s compact. You can hide the "messy" parts of your data and only show the clean, useful bits.&lt;/li&gt;
&lt;li&gt;It’s Secure: You can let a co-worker or Business Analyst see a View of the data without giving them access to the other data in the main table (sensitive information like credit card numbers or addresses).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's talk about "View" in Snowflake&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Snowflake has a few different types, but here are the three you'll hear about most.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard Views&lt;/strong&gt;&lt;br&gt;
The most common. They don't take up any extra space. They just run your query the moment you ask for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure Views&lt;/strong&gt;&lt;br&gt;
These are like standard views but with a "privacy shield." They stop people from seeing the secret code inside the view. You can learn more about Secure Views on Snowflake Documentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Materialized Views&lt;/strong&gt;&lt;br&gt;
These are the "pro" version of views. They actually save a copy of the results to make things super fast, but they cost a little extra money because they use storage and compute.&lt;/p&gt;

&lt;p&gt;In summary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F539ha1smhhfc02y3rg9b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F539ha1smhhfc02y3rg9b.jpg" alt="Comparison of Snowflake Views" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;Snowflake views have limitations regarding performance, data manipulation operations, and structure. Standard views are not pre-computed (can be slow), while Materialized Views have strict limitations, including single-table restriction, no joins, no window functions, and no non-deterministic functions, often leading to higher storage and compute costs. &lt;/p&gt;

&lt;p&gt;Key limitations of Snowflake views include-  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standard Views&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot be updated via ALTER VIEW , the entire table must be replaced.&lt;/li&gt;
&lt;li&gt;They do not cache data, meaning they compute results on every query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Materialized Views&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cannot join multiple tables, cannot query other views, cannot use ORDER BY, LIMIT, HAVING, or window functions.&lt;/li&gt;
&lt;li&gt;Require background compute for maintenance, making them unsuitable for frequently updated data.&lt;/li&gt;
&lt;li&gt;You cannot run INSERT, UPDATE, or DELETE directly on materialized views.&lt;/li&gt;
&lt;li&gt;Non-secure views may not be directly shared; Secure Views are required for sharing, which can limit query performance optimization. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, for complex, high-latency queries, Dynamic Tables are often recommended over Materialized Views to overcome these constraints. In professional environments, to overcome these trade-offs, dbt is widely used along with Snowflake. In another words, dbt can manually managed Snowflake views by treating them as "models".&lt;/p&gt;
&lt;h2&gt;
  
  
  How to Create VIEW
&lt;/h2&gt;

&lt;p&gt;It is simple and straightforward to create Standard "View". For this, you use CREATE VIEW or CREATE OR REPLACE VIEW.&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;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;My_First_View&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_table&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Manila'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make it secure, you just add the word SECURE right before VIEW.&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;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="n"&gt;SECURE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;My_First_Secure_View&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_table&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Manila'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make it materialized, you add the word MATERIALIZED.&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;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="n"&gt;MATERIALIZED&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;My_First_Materialized_View&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_table&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Manila'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ref: &lt;a href="https://docs.snowflake.com/en/user-guide/views-introduction" rel="noopener noreferrer"&gt;Snowflake Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>snowflake</category>
      <category>database</category>
      <category>data</category>
    </item>
  </channel>
</rss>
