0

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:

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?

2 Answers 2

2

When using SQLAlchemy you should strive to understand what takes place in Python and what in the database. 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.

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.

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.

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:

    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:

    # 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)
Sign up to request clarification or add additional context in comments.

Comments

0

You can use Datetime instance of TIMESTAMP

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)

1 Comment

The column's still nullable though, and the (static) default is not used in pandas.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.