3

I am using SQLModel in python 3.8

When I add my datetime field created_at: datetime = Field(default_factory=utcnow(), nullable=False)

I get this Error

File "./app/main.py", line 16, in <module>
    class Post(SQLModel, table=True):
  File "/Users/markwardell/PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/sqlmodel/main.py", line 277, in __new__
    new_cls = super().__new__(cls, name, bases, dict_used, **config_kwargs)
  File "pydantic/main.py", line 204, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 488, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 419, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 539, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 801, in pydantic.fields.ModelField.populate_validators
  File "pydantic/validators.py", line 718, in find_validators
RuntimeError: error checking inheritance of <module 'datetime' from '/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/datetime.py'> (type: module)

If I do not the add the created_at the table is created in PostgresSql as expected. Code

import datetime
from typing import Optional
import utcnow as utcnow
from fastapi import FastAPI
from sqlalchemy import TIMESTAMP, text
from sqlmodel import Field, Session, SQLModel, create_engine, select
from app.database import SQLALCHEMY_DATABASE_URL

class Hero(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True)
    name: str = Field(index=True)
    secret_name: str
    age: Optional[int] = Field(default=None, index=True)


class Post(SQLModel, table=True):
    id: Optional[int] = Field(default=None, primary_key=True, nullable=False)
    title: str = Field(nullable=False)
    content: str = Field(nullable=False)
    published: bool = Field(default=True, nullable=False)
    created_at: datetime = Field(default_factory=utcnow(), nullable=False)

engine = create_engine(SQLALCHEMY_DATABASE_URL)


def create_db_and_tables():
    SQLModel.metadata.create_all(engine)


app = FastAPI()


@app.on_event("startup")
def on_startup():
    create_db_and_tables()
Mark Wardell
  • 493
  • 7
  • 25

2 Answers2

11

Also, note that your code should be

created_at: datetime.datetime = Field(default_factory=datetime.utcnow, nullable=False)

without calling utcnow on instantiation, doing so will give every entry datetime as consulted at instantiation. Thus, default_factory should be the function, not the value.

Ignacio Vergara Kausel
  • 5,521
  • 4
  • 31
  • 41
Dariosky
  • 371
  • 4
  • 8
8

This was explained in a comment, but just to add it as an answer for others:

You must import datetime like this

from datetime import datetime

The datetime we require in this context is a actually a class inside a module that is also called datetime.

John Kealy
  • 1,503
  • 1
  • 13
  • 32