为什么我会"TypeError: id() takes exactly one argument (0 given)"?



我已经创建了一个time_zones表。当我尝试填充它时,我得到一个TypeError,说我需要包含一个id值。

from postgresql:

d+ time_zones
                                                         Table "public.time_zones"
   Column   |            Type             |                        Modifiers                        | Storage  | Stats target | Description 
------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
 id         | integer                     | not null default nextval('time_zones_id_seq'::regclass) | plain    |              | 
 name       | character varying(128)      | not null                                                | extended |              | 
 created_at | timestamp without time zone |                                                         | plain    |              | 
 updated_at | timestamp without time zone |                                                         | plain    |              | 
Indexes:
    "time_zones_pkey" PRIMARY KEY, btree (id)
    "time_zones_name_key" UNIQUE CONSTRAINT, btree (name)
Referenced by:
    TABLE "app_users" CONSTRAINT "app_users_time_zone_id_fkey" FOREIGN KEY (time_zone_id) REFERENCES time_zones(id)

来自models.py的TimeZone类:

class TimeZone(db.Model):
  __table_name__ = 'time_zones'
  id = db.Column(db.Integer, db.Sequence('time_zones_id_seq'), primary_key=True, nullable=False)
  name = db.Column(db.String(128), nullable=False)
  created_at = db.Column(db.TIMESTAMP(timezone=False), default=_get_date)
  updated_at = db.Column(db.TIMESTAMP(timezone=False), onupdate=_get_date)

Alembic迁移文件:

def upgrade():
  op.create_table('time_zones',
                  sa.Column('id', sa.Integer, primary_key=True, nullable=False),
                  sa.Column('name', sa.String(128), nullable=False, unique=True),
                  sa.Column('created_at', sa.TIMESTAMP(timezone=False), default=_get_date),
                  sa.Column('updated_at', sa.TIMESTAMP(timezone=False), onupdate=_get_date))

我的尝试添加一个名称到time_zones表通过烧瓶壳与TypeError:

>>> from app.main.models import TimeZone
>>> from app import db
>>> 
>>> tz = TimeZone(name='Central Time (US & Canada)')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 2, in __init__
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/instrumentation.py", line 347, in _new_state_if_none
    state = self._state_constructor(instance, self)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/util/langhelpers.py", line 747, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/instrumentation.py", line 177, in _state_constructor
    self.dispatch.first_init(self, self.class_)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/event/attr.py", line 256, in __call__
    fn(*args, **kw)
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/mapper.py", line 2860, in _event_on_first_init
    configure_mappers()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/mapper.py", line 2756, in configure_mappers
    mapper._post_configure_properties()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/mapper.py", line 1710, in _post_configure_properties
    prop.init()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/interfaces.py", line 183, in init
    self.do_init()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/relationships.py", line 1612, in do_init
    self._process_dependent_arguments()
  File "/usr/local/lib/python3.4/dist-packages/sqlalchemy/orm/relationships.py", line 1637, in _process_dependent_arguments
    setattr(self, attr, attr_value())
TypeError: id() takes exactly one argument (0 given)

更新

如果我在app.auth.models中从AppUser类中删除关系,我不再得到此错误。所以我一定没有把我的关系设置好。

以下是auth模块中的models.py:

class AppUser(UserMixin, Base):
  __tablename__ = 'app_users'
  username = db.Column(db.String(128), nullable=False, unique=True)
  firstname = db.Column(db.String(128))
  lastname = db.Column(db.String(128))
  email = db.Column(db.String(128), nullable=False)
  phone = db.Column(db.VARCHAR(12))
  company = db.Column(db.String(32))
  password_hash = db.Column(db.String(255), nullable=False)
  # When I kill these two lines I do not get the error.
  #time_zone_id = db.Column(db.Integer, db.ForeignKey('time_zones.id', ondelete='cascade'))
  #time_zone = db.relationship('TimeZone', backref='app_users', order_by=id)
  def __init__(self, username, email, password, firstname, lastname, company, phone):
    self.username = username.lower()
    self.email = email.lower()
    self.firstname = firstname.title()
    self.lastname = lastname.title()
    self.company = company
    self.phone = phone
    #self.time_zone_id = time_zone_id
    self.set_password(password)

  def set_password(self, password):
    self.password_hash = generate_password_hash(password)
  def verify_password(self, password):
    return check_password_hash(self.password_hash, password)
  def __repr__(self):
        return '<User %r>' % self.username

可疑问题

我刚刚在我自己的代码中解决了一个类似的问题,其中问题是在定义您在"UPDATE"中注释掉的关系的行上的order_by=id。当以这种方式声明排序时,SQLAlchemy会尝试使用AppUser的id属性来执行排序,因为声明是在AppUser类中。由于AppUser没有名为'id'的列或其他属性,python将访问内置的id()方法,该方法不能在没有参数的情况下使用(并且对于排序关系也没有用处)。

<标题>解决方案

我敢打赌,将order_by参数更改为order_by=TimeZone.idorder_by="TimeZone.id"将清除错误;类似的修改修复了我的代码中的问题。

相关内容

最新更新