Why does inserting records into a MariaDB table fail in a Dockerized PHP 7.1 Yii 1.1 application (NGINX + PHP + MariaDB 10) with SQLSTATE[HY000]: General error: 1364 Field ‘data_field’ doesn’t have a default value, but works fine on the original server?
Details:
- Moved project from backups to Docker, copied configs, same packages (PHP 7.1, Yii 1.1, MariaDB 10).
- Table has NOT NULL fields without defaults; frontend doesn’t provide values for them.
- Original server has worked without errors for years.
- Docker setup correctly enforces constraints, causing failure.
Where should I investigate to find why the original server bypasses this issue?
MariaDB Error 1364 hits your Dockerized PHP 7.1 Yii 1.1 app because the container’s MariaDB 10 defaults to strict sql_mode with STRICT_TRANS_TABLES enabled, blocking inserts into NOT NULL fields like ‘data_field’ without values or defaults. Your original server probably runs a lax legacy sql_mode—think empty or just NO_ENGINE_SUBSTITUTION—letting Yii’s CActiveRecord slip in empty strings or NULLs for years without complaint. Quick check: run SHOW VARIABLES LIKE 'sql_mode'; on both to spot the difference, then tweak Docker’s config to match.
Contents
- Understanding MariaDB Error 1364
- SQL Mode: The Real Culprit
- Why Docker MariaDB Goes Strict
- Yii 1.1 Insert Quirks in PHP 7.1
- Troubleshooting Steps
- Fixing It in Your Docker Setup
- Migration Best Practices
- Sources
- Conclusion
Understanding MariaDB Error 1364
Ever moved an old app to Docker and watched it crumble on something that worked forever? That’s your story. SQLSTATE[HY000]: General error: 1364 screams when MariaDB tries to insert into a NOT NULL column without a default value, and your frontend skips providing one. In Yii 1.1, models like CActiveRecord often omit fields during save(), assuming the DB handles it gracefully.
But why now? Pre-Docker, your original server shrugged it off. Docker MariaDB 10 doesn’t. This isn’t a schema bug—your table’s fine. It’s behavior. Dig into MariaDB’s official docs on Error 1364: strict mode (default since 10.2.4) treats missing values as fatal, unlike older lax setups that warn and convert NULL to empty strings.
Picture this: Yii crafts an INSERT skipping ‘data_field’. Legacy MySQL? “Eh, empty string it is.” Docker? “Nope. Error.” Frustrating, right?
SQL Mode: The Real Culprit
Sql_mode controls how MariaDB parses and validates SQL. It’s a comma-separated flag list, and STRICT_TRANS_TABLES (or STRICT_ALL_TABLES) is the villain here. Enable it, and NOT NULL fields demand explicit values—no defaults? Boom, 1364.
Your original server likely inherited MySQL 5.x vibes: sql_mode set to ‘’ (empty) or minimal like NO_ENGINE_SUBSTITUTION. Common in long-running PHP apps. Yii 1.1 thrived there because CDBCommand let PDO emulate prepares loosely.
Docker MariaDB? Packs strict mode out of the box. Stack Overflow nails it: verify with mysql -u root -p -e "SHOW VARIABLES LIKE 'sql_mode';" on both servers. Original might show just legacy flags; Docker spits a wall of STRICT_ goodies.
What if sql_modes match? Rare, but check Yii’s PDO attrs—PDO::ATTR_EMULATE_PREPARES true can mask issues, though server sql_mode trumps client tweaks.
And the gap widens post-10.2: MariaDB hardened defaults for data integrity. Your backups from lax eras expose the shift.
Why Docker MariaDB Goes Strict
Docker images like mariadb:10 boot with production-ready settings. Strict sql_mode prevents sloppy data—great for new apps, nightmare for legacy Yii ports. No custom my.cnf? You inherit ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,STRICT_TRANS_TABLES etc.
Original server? Probably a hand-tuned my.cnf from 2010s: sql_mode=NO_ENGINE_SUBSTITUTION only, bypassing NOT NULL checks. Or pre-10.2 MariaDB/MySQL, where strict was optional.
OwnCloud’s GitHub issue mirrors your pain: Docker MariaDB rejects inserts on NOT NULL like ‘publicuri’; legacy didn’t. They compared SHOW VARIABLES—Docker strict, host lax.
NGINX + PHP 7.1 + Yii? Irrelevant. It’s pure DB. But Docker isolation means no global tweaks bleed in. Container restarts reset to strict.
Quick test: Spin up Docker shell, query sql_mode. Matches the error? Culprit confirmed.
Yii 1.1 Insert Quirks in PHP 7.1
Yii 1.1’s ancient but battle-tested. CActiveRecord::save() builds INSERT from attributes, skipping unset fields. If ‘data_field’ lacks a default and frontend ignores it? Yii sends NULL or omits—fine in lax mode.
PHP 7.1? Compatible, but PDO stricter than PHP 5.x. Still, server sql_mode rules.
Yii forum thread hits home: MariaDB strict kills Yii inserts where MySQL didn’t. Debug: Dump original sql_mode via mysqldump, replicate in Docker.
Does Yii set empty strings? Sometimes. But NOT NULL without DEFAULT rejects even ‘’. Lax mode converts; strict doesn’t.
Pro tip: Log Yii queries (yiic log). Spot the bare INSERT sans ‘data_field’.
Troubleshooting Steps
Don’t guess—probe.
-
Compare sql_modes: Original server:
SHOW VARIABLES LIKE 'sql_mode';. Docker:docker exec -it mariadb mysql -uroot -p -e "SHOW VARIABLES LIKE 'sql_mode';'. -
Test insert manually: Docker MySQL shell:
INSERT INTO your_table (other_fields) VALUES (...);. Fails? Strict confirmed. -
Yii logs: Enable
YII_DEBUG=true, check/protected/runtime/application.logfor full SQLSTATE. -
Schema dump:
mysqldump --no-data original_db | grep -i default. Verify NOT NULLs. -
Versions:
SELECT VERSION();both sides. MariaDB 10+ strict default.
Database.guide lists 5 fixes, but start with sql_mode—non-invasive.
Original bypasses? Lax sql_mode or older MariaDB. Docker enforces for safety.
Stuck? Diff my.cnf or docker-compose volumes.
Fixing It in Your Docker Setup
No schema changes? Tweak sql_mode to legacy.
Option 1: Docker command override (docker-compose.yml):
services:
mariadb:
image: mariadb:10
command: --sql_mode="NO_ENGINE_SUBSTITUTION"
# or empty: --sql_mode=""
Option 2: Custom my.cnf:
Mount volume:
volumes:
- ./my.cnf:/etc/mysql/conf.d/my.cnf
my.cnf:
[mysqld]
sql_mode = "NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
# Drop STRICT_TRANS_TABLES
Option 3: Init script (Dockerfile or entrypoint.sh):
#!/bin/bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';"
exec docker-entrypoint.sh "$@"
Restart container. Inserts fly. Matches original.
Schema fixes? ALTER TABLE your_table MODIFY data_field VARCHAR(255) DEFAULT '';. But legacy hacks first.
Yii tweak: Override model beforeSave() to set ‘’ on empty fields.
Migration Best Practices
Dockerizing old Yii? Expect sql_mode shocks.
- Audit sql_mode early—script both servers.
- Use multi-stage: Test strict first, loosen if needed.
- Don’t blank sql_mode fully—keep sane flags like
NO_ZERO_DATE. - Version pin:
mariadb:10.6if 10.x varies. - CI/CD: Bake sql_mode into images.
- Future-proof: Add defaults gradually, fix Yii models.
Strict mode’s better long-term—clean data. But for quick wins, emulate original.
Questions? What does your sql_mode show?
Sources
- mysql error 1364 Field doesn’t have a default values - Stack Overflow
- Error 1364: Field doesn’t have a default value - MariaDB Knowledge Base
- 5 Ways to Fix Error 1364 “Field ‘…’ doesn’t have a default value” in MySQL
- SQLSTATE[HY000]: General error: 1364 Field ‘publicuri’ doesn’t have a default value · Issue #39320 · owncloud/core
- MariaDB vs MySQL on YII - General Discussion - Yii Framework Forum
Conclusion
MariaDB Error 1364 boils down to sql_mode mismatch: Docker’s strict STRICT_TRANS_TABLES vs. your original server’s lax setup letting Yii 1.1 inserts slide. Diagnose with SHOW VARIABLES LIKE 'sql_mode';, then override in docker-compose or my.cnf for instant relief. Long-term, add defaults and tighten Yii—your app’s more robust. Migrate smarter next time by matching configs upfront.