9

I have a database schema (which i cannot change) with dates. they are defined as:

+---------------------+------------------+------+-----+---------+----------------+
| Field               | Type             | Null | Key | Default | Extra          |
+---------------------+------------------+------+-----+---------+----------------+
| id                  | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
...
| access_date         | int(10) unsigned | NO   |     | 0       |                |
+---------------------+------------------+------+-----+---------+----------------+

now, my model as this as defined:

 from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class logme(Base):

  id_ = Column(Integer, primary_key=True)
  ...
  access_date = Column(Integer, nullable=False, server_default=0)

When i load the model i get this error:

sqlalchemy.exc.ArgumentError: Argument 'arg' is expected to be one of type '<class 'str'>' or '<class 'sqlalchemy.sql.elements.ClauseElement'>' or '<class 'sqlalchemy.sql.elements.TextClause'>', got '<class 'int'>'

if I comment out the access_date everything works fine

Pat R Ellery
  • 1,696
  • 3
  • 22
  • 40

2 Answers2

15

You are using server_default= parameter and instead, you need to change it to use the default= parameter. More info in the links to docs below.

Maybe this will help? (http://docs.sqlalchemy.org/en/rel_1_0/core/defaults.html)

Scalar Defaults

The simplest kind of default is a scalar value used as the default value of a column:

Table("mytable", meta, Column("somecolumn", Integer, default=12) ) Above, the value “12” will be bound as the column value during an INSERT if no other value is supplied.

You are using server_default parameter

server_default=0

which is explained here

Server Side Defaults¶

A variant on the SQL expression default is the server_default, which gets placed in the CREATE TABLE statement during a create() operation:

t = Table('test', meta, Column('abc', String(20), server_default='abc'), Column('created_at', DateTime, server_default=text("sysdate")) ) A create call for the above table will produce:

CREATE TABLE test ( abc varchar(20) default 'abc', created_at datetime default sysdate ) The behavior of server_default is similar to that of a regular SQL default; if it’s placed on a primary key column for a database which doesn’t have a way to “postfetch” the ID, and the statement is not “inlined”, the SQL expression is pre-executed; otherwise, SQLAlchemy lets the default fire off on the database side normally.

Bob Jordan
  • 3,049
  • 2
  • 34
  • 41
Alex
  • 467
  • 3
  • 8
8

I think the error is self-explanatory

Argument 'arg' is expected to be one of type '<class 'str'>' ....
got '<class 'int'>'

Change the line as follows :

access_date = Column(Integer, nullable=False, server_default="0")

Please put quotes around zero. Since the column is defined as Integer the server side default will be numeric zero, and not string "0"


On unrelated note, I think you need either nullable=False or server_default, not both.

When you say nullable=False you expect a value to be provided explicitly in your INSERT statement, so server_default won't be needed.

OTOH, server_default indicates that it is OK to not provide value in your INSERT statement, but DB server will still populate it with your server_default

Mandar Vaze
  • 1,324
  • 13
  • 20
  • Both `nullable` and `server_default` might be needed when adding a column to an existing table with existing data. Still, consider removing the default value if that is not your expected db behaviour. – jkulak Nov 06 '22 at 20:52