SQLAlchemy 是 python 中常用都ORM的组建,在Flask 中广泛使用。
default 和server_default :
default = 默认值只在使用SQLAlchemy创建数据时候才生效, 如果想要在任何地方都生效需要使用 server_default
二者联系和区别
在官方手册里可以看到,对二者是支持的,在Datatime 'YYYY-MM-DD hh:mm:ss' 格式下 与
TIMESTAMP的格式 '2038-01-19 03:14:07'
UTC是等效的
不同之处是:
Datatime 范围是 The supported range is '1000-01-01 00:00:00'
to '9999-12-31 23:59:59'
.
TIMESTAMP has a range of '1970-01-01 00:00:01'
UTC to '2038-01-19 03:14:07'
UTC.
范围不同,书写格式不同UTC。
Datetime 的server_default 一般使用使用func.utime(), 求一次时间的结果
TIMESTAMP 的server_default 一般使用text("CURRENT_TIMESTAMP"), 从系统中获得 CURRENT_TIMESTAMP 是个时间变量
在这里我们创建2个表,验证Datetime 和TIMESTAMP 两种格式的时间
class TestData1(db.Model):
__tablename__ = 'test1'
id= db.Column(db.INTEGER,primary_key=True,autoincrement=True)
name=db.Column(db.String(64),default="hello")
ctime0 = db.Column(db.DateTime)
ctime1 = db.Column(db.DateTime,nullable=False)
ctime2 = db.Column(db.DateTime,nullable=False, default=datetime.utcnow())
ctime3 = db.Column(db.DateTime,nullable=False, server_default=func.now())
ctime4 = db.Column(db.DateTime,nullable=False, server_default=func.now(),server_onupdate=func.now())
ctime5 = db.Column(db.DateTime,nullable=False, server_default=func.now())
ctime6 = db.Column(db.DateTime,nullable=False, server_default=func.now(), onupdate=func.now())
class TestData2(db.Model):
__tablename__ = 'test2'
id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
name = db.Column(db.String(64), default="hello")
utime0 = db.Column(db.TIMESTAMP)
utime1 = db.Column(db.TIMESTAMP,nullable=False)
utime2 = db.Column(db.TIMESTAMP(True))
utime3 = db.Column(db.TIMESTAMP(True),nullable=False)
utime4 = db.Column(db.TIMESTAMP(True),nullable=False,default=db.text('CURRENT_TIMESTAMP'))
utime5 = db.Column(db.TIMESTAMP(True),nullable=False,server_default=db.text('CURRENT_TIMESTAMP'))
utime6 = db.Column(db.TIMESTAMP(True),nullable=False,default=db.text('CURRENT_TIMESTAMP'),server_default=db.text('CURRENT_TIMESTAMP'))
utime7 = db.Column(db.TIMESTAMP(True),nullable=False,server_default=db.text('CURRENT_TIMESTAMP'),onupdate=db.text('CURRENT_TIMESTAMP'))
utime8 = db.Column(db.TIMESTAMP(True),nullable=False,default=db.text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))
然后我们生成表,使用flask shell 来测试。
通过 sqlalchemy 来更新数据
>>> read_td1()
ctime0 = 2021-02-04 03:14:31
ctime1 = 2021-02-04 03:14:29
ctime2 = 2021-02-04 03:14:50
ctime3 = 2021-02-04 11:14:37
ctime4 = 2021-02-04 11:14:37
ctime5 = 2021-02-04 11:14:37
ctime6 = 2021-02-04 11:14:37
>>> D1 = TestData1.query.filter_by(id=1).first()
>>> D1.name
'200'
>>> D1.name="201"
>>> db.session.commit()
>>> read_td1()
ctime0 = 2021-02-04 03:14:31
ctime1 = 2021-02-04 03:14:29
ctime2 = 2021-02-04 03:14:50
ctime3 = 2021-02-04 11:14:37
ctime4 = 2021-02-04 11:14:37
ctime5 = 2021-02-04 11:14:37
ctime6 = 2021-02-04 11:26:22
>>>
手动更新数据,即直接操作DB
>>> read_td1()
ctime0 = 2021-02-04 03:14:31
ctime1 = 2021-02-04 03:14:29
ctime2 = 2021-02-04 03:14:50
ctime3 = 2021-02-04 11:14:37
ctime4 = 2021-02-04 11:14:37
ctime5 = 2021-02-04 11:14:37
ctime6 = 2021-02-04 11:26:22
>>> from sap.models import db,TestData1,TestData2
KeyboardInterrupt
>>> D1 = TestData1.query.filter_by(id=1).first()
>>> D1.name
'208'
通过sqlalchemy 来更新test2 表
>>> print(*["{} = {}".format(key,getattr(D2,key)) for key in map(lambda x:"utime{}".format(x),range(9))],sep="\n")
utime0 = None
utime1 = 2021-02-04 03:36:46
utime2 = None
utime3 = 2021-02-04 03:36:57
utime4 = 2021-02-04 03:37:01
utime5 = 2021-02-04 11:37:09
utime6 = 2021-02-04 11:37:09
utime7 = 2021-02-04 11:37:09
utime8 = 2021-02-04 03:37:07
>>> D2.name="gg"
>>> db.session.commit()
>>> D2= TestData2.query.filter_by(id=1).first()
>>> D2.name
'gg'
>>> print(*["{} = {}".format(key,getattr(D2,key)) for key in map(lambda x:"utime{}".format(x),range(9))],sep="\n")
utime0 = None
utime1 = 2021-02-04 03:36:46
utime2 = None
utime3 = 2021-02-04 03:36:57
utime4 = 2021-02-04 03:37:01
utime5 = 2021-02-04 11:37:09
utime6 = 2021-02-04 11:37:09
utime7 = 2021-02-04 11:39:55
utime8 = 2021-02-04 03:37:07
>>>
手动操作数据库
mysql> update test2 set name="baba" where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from test2\G;
*************************** 1. row ***************************
id: 1
name: baba
utime0: NULL
utime1: 2021-02-04 03:36:46
utime2: NULL
utime3: 2021-02-04 03:36:57
utime4: 2021-02-04 03:37:01
utime5: 2021-02-04 11:37:09
utime6: 2021-02-04 11:37:09
utime7: 2021-02-04 11:39:55
utime8: 2021-02-04 03:37:07
1 row in set (0.00 sec)
>>> D2= TestData2.query.filter_by(id=1).first()
>>> D2.name
'baba'
>>> print(*["{} = {}".format(key,getattr(D2,key)) for key in map(lambda x:"utime{}".format(x),range(9))],sep="\n")
utime0 = None
utime1 = 2021-02-04 03:36:46
utime2 = None
utime3 = 2021-02-04 03:36:57
utime4 = 2021-02-04 03:37:01
utime5 = 2021-02-04 11:37:09
utime6 = 2021-02-04 11:37:09
utime7 = 2021-02-04 11:39:55
utime8 = 2021-02-04 03:37:07
>>>
通过sqlalchemy 使用 时候,models 中可以使用这2种格式 创建自动更新时间的字段:
ctime6 = db.Column(db.DateTime,nullable=False, server_default=func.now(), onupdate=func.now())
或者
utime7 = db.Column(db.TIMESTAMP(True),nullable=False,server_default=db.text('CURRENT_TIMESTAMP'),onupdate=db.text('CURRENT_TIMESTAMP'))
能做到自动更新时间。