Direct database writes bypass everything Magento does for you
Magento provides models, resource models, and service contracts for writing data, and they exist for good reasons. Custom modules that skip them and write raw SQL directly to the database bypass all of that protection.
A direct write to a core table can look like a shortcut and behave like a landmine. It skips validation, events, indexing, and cache invalidation, and it can open a path to SQL injection.
This article covers what direct writes skip, the specific risks they create, how to find them in a codebase, and what the correct approach looks like.
What a direct write skips
When you save a product through Magento's normal path, a lot happens beyond the row changing. Validation runs, events fire, the relevant indexes are marked for update, and cached content is invalidated.
A direct SQL write to the same table does none of that. It changes the row and nothing else, leaving indexes stale, caches serving old content, and any logic that should have run on the change simply skipped.
The data-integrity risk
Core tables are related, and Magento's write layer keeps those relationships consistent. Writing directly to one table without the others is how catalog, inventory, and sales data drift apart.
An integration that updates stock by writing straight to the inventory table, for example, can set a quantity without updating stock status or triggering the reindex that would reconcile the two. The number changes, but the derived data does not follow.
This is a frequent root cause of wrong stock, incorrect prices, and orders that reference inconsistent data. The direct write saved a step and created a discrepancy.
The SQL injection risk
Raw SQL built by concatenating variables into a query string is a classic injection vector. If any of those values comes from user input, an attacker can manipulate the query.
Magento's database layer supports bound parameters precisely to prevent this. Custom code that builds queries by string concatenation, rather than binding parameters, exposes the store to injection on exactly the inputs it fails to escape.
This turns a data shortcut into a security vulnerability. A direct write is not only an integrity risk; done carelessly, it is an attack surface.
The upgrade-coupling risk
Direct writes hard-code assumptions about the database structure. They name tables and columns directly, which couples the custom code to a schema that Magento controls and changes.
When an upgrade changes that structure, the direct write breaks, often silently, because nothing checks that the table still looks the way the code assumed. Code that went through the service contracts would have been insulated from the change.
This is why direct writes age badly. They work until the schema moves, and then they fail in ways that are hard to connect back to an upgrade.
Finding direct writes in the code
Direct writes are searchable. They tend to use a recognizable set of methods to get a raw connection and execute SQL.
Grep the custom modules for the patterns: calls that fetch a connection and run query, insert, or update against core table names. A resource connection used to write to sales_order, quote, or the catalog tables is the strongest signal.
grep -rn "getConnection()" app/code | grep -iE "->query\(|->insert\(|->update\(|->delete\("
Every hit is a candidate to review. Not all raw queries are wrong, but every one writing to a core table deserves a close look.
What the correct approach looks like
The right way to change data is through Magento's own layers. Repositories and service contracts handle entities like products, orders, and customers while maintaining the relationships and firing the events.
For a module's own custom tables, resource models with declarative schema are the standard, and they keep the code decoupled from raw SQL. When a query genuinely must be raw, bound parameters rather than string concatenation are non-negotiable.
These approaches are more code than a direct write, and that is the trade. They cost a little more to write and save the integrity, security, and upgrade problems the shortcut creates.
Bulk operations are the tempting case
The strongest temptation to write raw SQL is bulk work. Updating a hundred thousand products through the normal save path is slow, and a direct bulk update is dramatically faster.
The speed is real, and so is the cost. A direct bulk update skips the indexing and cache invalidation that the change requires, so the fast write leaves the storefront showing stale data until a separate reindex catches up.
Magento provides bulk-friendly APIs and import paths that keep the relationships intact for exactly this reason. When raw bulk writes are genuinely necessary, they must be paired with the explicit reindex and cache invalidation they skipped, or the store is fast and wrong.
Shortcuts that cost later
A direct database write is a small saving now and a standing risk afterward. It skips the work Magento does to keep data consistent, secure, and upgrade-safe, and it does so invisibly.
Knowing where your custom modules write directly to the database, and whether those writes touch core tables or user input, turns a hidden risk into a reviewable list. Finding unsafe direct writes is a core part of a security and module-quality review.