我刚刚在我的postgresql数据库上运行了一个alembic升级。“之前”和“之后”之间的差异表明,尽管只有一些表被修改,但所有表都被重写。更改仅发生在datetime列中,如下所示:
< 202 dac1d06a-e9e1-4739-a80c-9ae913e345c3 2023-05-23 12:05:58.972111+00 199 \N 139 \N dut001 f \N script initial commit f
< 203 410ced4d-e2cf-4006-8cf0-f143f744f953 2023-05-23 12:05:58.980174+00 199 \N 141 201 duthandler t \N script initial commit f
> 202 dac1d06a-e9e1-4739-a80c-9ae913e345c3 2023-05-23 14:05:58.972111+02 199 \N 139 \N dut001 f \N script initial commit f
> 203 410ced4d-e2cf-4006-8cf0-f143f744f953 2023-05-23 14:05:58.980174+02 199 \N 141 201 duthandler t \N script initial commit f
字符串
这些表最初是通过sqlalchemy生成的:
class MyClass(Base):
__tablename__ = "alias_map_expanded"
seq2 = Sequence(name="seq2")
id = Column(
BigInteger, sumo_seq2, server_default=seq2.next_value(), primary_key=True
)
uuid = Column(
UUID(as_uuid=True), server_default=func.gen_random_uuid(), nullable=False
)
creation_date = Column(
DateTime(timezone=True), server_default=func.current_timestamp(), nullable=False
)
...
型
现在我已经读到了naive和non-naive的时间戳,并了解了如何在python中从一个时间戳到另一个时间戳,但我真的被为什么在升级过程中会发生这种情况以及如何避免时间戳一起改变的问题所困扰。
提前感谢!
1条答案
按热度按时间aurhwmvo1#
chatGPT应答
您在alembic升级过程中遇到的问题似乎与PostgreSQL数据库中更新的时间戳有关。这种行为的原因可能是由于SQLAlchemy模型的定义方式以及alembic处理模型更改的方式。
问题是由为
creation_date
列提供的server_default
属性引起的。当您定义server_default=func.current_timestamp()
时,每当向表中插入新行时,它都会将列的默认值设置为当前时间戳。这是在插入时使用当前时间自动填充时间戳列的常用方法。您在diff中看到的时间戳的差异是由于时区的更改。“之前”时间戳的时区为+00,而“之后”时间戳的时区为+02。这表示服务器的时区在两个时间戳之间发生了更改。
alembic升级重写所有表的问题与alembic跟踪并将更改应用于数据库模式的方式有关。当alembic检测到模型定义中的更改时,例如更改列默认值,它会生成必要的SQL命令来应用更改。在本例中,由于
creation_date
列有一个新的默认值,并且时区不同,alembic将生成SQL命令,用新的默认值更新表中所有现有的行。为了避免在升级期间更改时间戳,您有几个选项:
1.删除
creation_date
列的server_default
:如果不希望creation_date
列自动填充当前时间戳,可以从列定义中删除server_default
属性。这将阻止alembic生成SQL命令来更新现有行。字符串
请注意,删除
server_default
将要求您在手动插入新行时为creation_date
提供一个值。1.对
creation_date
列使用server_onupdate
:除了使用server_default
,您还可以使用server_onupdate
来仅在更新行时(而不是插入行时)自动更新creation_date
列。型
这样,
creation_date
列将仅在您修改行时自动更新,而不是在插入期间自动更新。1.在插入过程中手动设置
creation_date
值:如果希望对creation_date
列进行更多控制,并且不希望依赖于自动填充,则可以在向表中插入新行时手动设置creation_date
值。型
插入特定creation_date行示例
型
选择最适合您要求的选项。删除
server_default
或使用server_onupdate
可能会阻止升级过程中的自动更改,但也会更改creation_date
列的行为,因此请仔细考虑您的选择的含义。