我使用sqlalchemy创建一个表,我想在mysql中设置默认时间戳,但它无法插入到mysql中,我的代码:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, String, Integer, Float, ForeignKey,TIMESTAMP
Base = declarative_base()
DBSession = sessionmaker(bind=engine)
session = DBSession()
class Book(Base):
__tablename__ = 'book'
bid = Column(Integer, primary_key=True)
bname = Column(String(20))
price = Column(Integer)
student_id = Column(Integer, ForeignKey(Student.id))
student = relationship(Student)
insert_time = Column(TIMESTAMP(timezone=False),
default=datetime.datetime.now())
Base.metadata.create_all(engine)
books = pd.DataFrame({"bname": ['a','b','c','d'],
"price":[128,22,67,190],
'student_id':[1,1,3,2]})
books.to_sql('book',engine,if_exists='append',index=False)
看看book表,insert_time
字段是null
,不是datetime,我该如何处理?
最佳答案
使用 SQLAlchemy 时,您应该努力了解 Python 中发生的情况以及数据库中发生的情况。在这里,您使用 default
定义了 insert_time
的默认值。参数,与使用 server_default
相比,因此,如果未指定列的值,并且仅当您使用指定的模型或基础表
时,默认值就会添加到 Python 中的值中。
如果您根据所显示的模型创建了表,则没有服务器端默认值,并且该列可以为空。这很重要,因为 Pandas 使用自己的元数据进行批量插入,因此它不知道您的 Python 端默认值。
在 MySQL 中,取决于版本和标志,TIMESTAMP
类型的列隐式地 NOT NULL
与任何其他类型不同,并且第一个时间戳列的服务器端默认值为CURRENT_TIMESTAMP
,但是SQLAlchemy emits the NULL
specifier explicitly if nullable=False
未指定,以使行为与其他 DBMS 一致。
最后,您很可能打算将函数 datetime.datetime.now
作为默认值传递,而不是在类构造期间调用时获得的 datetime
实例功能:
insert_time = Column(TIMESTAMP(timezone=False),
default=datetime.datetime.now) # Don't call it, pass it
如果按照您所示使用 Pandas,您还应该显式指定服务器端默认值:
# Having `default` as well is a bit redundant.
insert_time = Column(TIMESTAMP(timezone=False),
default=datetime.datetime.now,
server_default=text('CURRENT_TIMESTAMP'),
nullable=False)
关于python - SQLAlchemy/ Pandas : Can not insert default time in MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52327311/