sqlalchemy does not emit server_onupdate ON UPDATE clause with MySQL
See original GitHub issueMigrated issue, originally created by Charles-Axel Dein (@charlax)
This seems similar to #3155 and #2631.
I have this simple script to reproduce the problem:
from sqlalchemy import create_engine
from sqlalchemy import func
from sqlalchemy.dialects.mysql import DATETIME
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import Column
from sqlalchemy.types import Integer, DateTime
Base = declarative_base()
class Timestamp(Base):
__tablename__ = 'timestamps'
id = Column(Integer(), primary_key=True)
created_at = Column(DateTime(), nullable=False,
server_default=func.current_timestamp())
updated_at = Column(DateTime(), nullable=False,
server_default=func.current_timestamp(),
server_onupdate=func.current_timestamp())
if __name__ == '__main__':
engine = create_engine('mysql://root:root@localhost/test', echo=True)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
The SQL that sqlalchemy generates does not have the ON UPDATE
clause:
CREATE TABLE timestamps (
id INTEGER NOT NULL AUTO_INCREMENT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
)
A SHOW CREATE TABLE
query confirms that fact:
CREATE TABLE `timestamps` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
I’m not 100% sure I’m not causing the problem or have fully understood the two similar tickets. I’ll read about it and follow up on this thread if I find something.
Issue Analytics
- State:
- Created 8 years ago
- Reactions:2
- Comments:8
Top Results From Across the Web
Column INSERT/UPDATE Defaults
The Column.server_onupdate directive does not currently produce MySQL's “ON UPDATE CURRENT_TIMESTAMP()” clause. See Rendering ON UPDATE CURRENT TIMESTAMP ...
Read more >How to set DEFAULT ON UPDATE CURRENT_TIMESTAMP ...
If all you want is DEFAULT CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP in MySQL, then just setting the TIMESTAMP column in sqlalchemy to ...
Read more >sqlalchemy Changelog - pyup.io
joined-inheritance subclass, updating only local table columns, where the "fetch" synchronization strategy would not render the correct RETURNING clause for ...
Read more >Column Insert/Update Defaults
When an update statement executes and no value is passed for last_updated ... specific to MySQL, when an UPDATE statement is emitted for...
Read more >SQLAlchemy - Quick Guide - Tutorialspoint
In MySQL, providing updates to column values is based on that of other column values. Following statement's result − UPDATE table1 SET x...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Charles-Axel Dein (@charlax) wrote:
Leaving this for future reference, and people who might stumble upon this: http://jasonbos.co/two-timestamp-columns-in-mysql/
So basically getting a model with database-level
created_at
andupdated_at
behavior requires some shenanigans that you recommend against in #3155. Sadly, wasn’t able to find another way to achieve this.Which outputs:
And then, you need to pass a value of NULL on create:
Charles-Axel Dein (@charlax) wrote:
Probably the last update here, left for posterity: was getting too complicated, so ended up defining all of this on the app side instead of database-side.