6

I have workspacestable

workspaces_table = Table(
    "workspaces", metadata_obj,
    Column("id", UUID(as_uuid=False), primary_key=True, default=uuid.uuid4),
    Column("name", JSONB(), nullable=False),
    Column("created_at", TIMESTAMP(timezone=False), default=datetime.datetime.now(), nullable=False),
    Column("updated_at", TIMESTAMP(timezone=False), default=datetime.datetime.now(), nullable=False),
    Column("created_by", UUID(as_uuid=False), ForeignKey('users.id'), nullable=False),
    Column("updated_by", UUID(as_uuid=False), ForeignKey('users.id'), nullable=False),
    Column("email", Text(), nullable=False)
)

In this table columns created_at and updated_at have default value datetime.datetime.now()

But when I try to insert row in this table like

  await conn.execute(text(
        f"""
            WITH workspace_create AS (
                INSERT INTO workspaces(id, name, created_by, updated_by, email)
                VALUES (:workspace_id, :workspace_name, :user_id, :user_id, :workspace_email)
            ),
            
            workspace_roles_create AS (
                INSERT INTO workspace_roles(id, name, export_data, users, settings, projects, roles, system_name,
                    workspace_id)
                VALUES {sql_query_workspace_roles_values}
            )
            
            INSERT INTO m2m_users_to_workspace_or_project_roles(user_id, role_id, role_type, user_status) 
            VALUES(:user_id, :superuser_id, '{RoleTypes.Workspace.name}', '{UserStatuses.Active.name}')
        """
    ), params
    )

I get following error:

null value in column "created_at" of relation "workspaces" violates not-null constraint
DETAIL:  Failing row contains (dd31dfb6-6d22-4794-b804-631e60b6e063, [{"locale": "ru", "text_value": "ru_team_1"}], null, null, 481b7a55-52b7-48f2-89ea-4ae0673d4ab6, 481b7a55-52b7-48f2-89ea-4ae0673d4ab6, [email protected]).

I see that row contains null instead default value in created_at updated_at columns.

How can I insert default values automatically?

1 Answer 1

3

Column(…, default=…) is a client-side default value that is used by SQLAlchemy Core (and SQLAlchemy ORM) when you do something like workspaces_table.insert(). Note that if SQLAlchemy creates the table then that column does not have a server-side DEFAULT:

workspaces_table = Table(
    "workspaces",
    MetaData(),
    Column("id", Integer(), primary_key=True),
    Column("created_at", DateTime(), default=datetime.now()),
)
engine.echo = False
workspaces_table.drop(engine, checkfirst=True)
engine.echo = True
workspaces_table.create(engine)
""" DDL emitted:
CREATE TABLE workspaces (
    id SERIAL NOT NULL, 
    created_at TIMESTAMP WITHOUT TIME ZONE, 
    PRIMARY KEY (id)
)
"""

Column(…, server_default=…) is what specifies the server-side DEFAULT which will be available to plain text INSERT statements like the one in your question:

workspaces_table = Table(
    "workspaces",
    MetaData(),
    Column("id", Integer(), primary_key=True),
    Column("created_at", DateTime(), server_default=text("CURRENT_TIMESTAMP")),
)
engine.echo = False
workspaces_table.drop(engine, checkfirst=True)
engine.echo = True
workspaces_table.create(engine)
""" DDL emitted:
CREATE TABLE workspaces (
    id SERIAL NOT NULL, 
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (id)
)
"""

Note that changing the Table() definition from default= to server_default= will not update an existing table; you'll need to use ALTER TABLE for that.

Sign up to request clarification or add additional context in comments.

Comments

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.