简体   繁体   English

SQLAlchemy / Pandas:无法在MySQL中插入默认时间

[英]SQLAlchemy/Pandas: Can not insert default time in MySQL

I create a table using sqlalchemy, and I want to set a default timestamp in mysql, but it can not insert into mysql, my code: 我使用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)

look at the book table, the insert_time field is null , not the datetime, how I deal with it? 看书表, insert_time字段为null ,而不是datetime,我该如何处理?

When using SQLAlchemy you should strive to understand what takes place in Python and what in the database. 使用SQLAlchemy时,您应该努力了解Python中发生了什么以及数据库中发生了什么。 Here you have defined a default value for insert_time using the default argument, compared to using server_default , so the default value is added to the values in Python , if no value for the column was specified, and only if you are using either the specified model or underlying Table . 与使用server_default相比,在这里您使用default参数定义了insert_time的默认值,因此,如果未指定列的值,并且仅当您使用指定的模型时,该默认值就会添加到Python中的值或基础Table

If you created the table based on the model you have shown, then there is no server side default value and the column is nullable. 如果基于显示的模型创建表,则没有服务器端默认值,并且该列可为空。 This matters, because Pandas does a bulk insert using its own metadata, so it does not know about your Python side default. 这很重要,因为Pandas使用自己的元数据进行批量插入,因此它不知道您的Python端默认设置。

In MySQL – depending on version and flags – a column of type TIMESTAMP is implicitly NOT NULL unlike any other type and the first timestamp column has a server side default of CURRENT_TIMESTAMP , but SQLAlchemy emits the NULL specifier explicitly if nullable=False is not specified, in order to make the behaviour consistent with other DBMS. 在MySQL中-根据版本和标志-与其他类型不同, TIMESTAMP类型的列隐式为NOT NULL并且第一个timestamp列的服务器端默认值为CURRENT_TIMESTAMP ,但如果未指定nullable=FalseSQLAlchemy显式发出NULL指定符,为了使行为与其他DBMS一致。

Finally, you most probably meant to pass the function datetime.datetime.now as the default, not an instance of datetime that you get during class construction when you call the function: 最后,您最有可能希望将函数datetime.datetime.now作为默认值传递,而不是在构造函数时调用该函数时获得的datetime实例:

    insert_time = Column(TIMESTAMP(timezone=False),
                         default=datetime.datetime.now)  # Don't call it, pass it

You should also explicitly specify a server side default, if using Pandas as you have shown: 如果使用的是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)

You can use Datetime instance of TIMESTAMP 您可以使用TIMESTAMP的Datetime实例

import datetime
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,DateTime

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(Datetime,
                         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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM