遵循正式的ORM教程,我遇到了错误

时间:2011-07-15 16:34:45

标签: sqlalchemy

只是一个抬头,我是一般的编程新手所以我猜我错过了一些简单的东西。我一直在努力关注官方tutorial here,而我正在Building Relationships部分。当它说没有'address'表时,它可以运行到最后一个session.commit()。这就是我认为代码应该做的事情;

  1. 地址设置表格。
  2. metadata.create_all(engine)在当前会话中创建表。
  3. 我设置了新用户'jack',包括一些地址。
  4. 我尝试添加'jack',然后提交。
  5. 我不确定我做错了什么,我很感激任何帮助。

    from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey, create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker, relationship, backref
    
    Base = declarative_base()
    metadata = MetaData()
    engine = create_engine('sqlite:///:memory:', echo=False)
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    users_table = Table('users', metadata,
                        Column('id', Integer, primary_key=True),
                        Column('name', String),
                        Column('fullname', String),
                        Column('password', String)
                        )
    
    
    
    class User(Base):
        __tablename__ = 'users'
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
        fullname = Column(String)
        password = Column(String)
    
        def __init__(self, name, fullname, password):
            self.name = name
            self.fullname = fullname
            self.password = password
    
        def __repr__(self):
           return "<User('%s', '%s', '%s')>" % (self.name, self.fullname, self.password)
    
    
    
    class Address(Base):
        __tablename__ = 'addresses'
        id = Column(Integer, primary_key=True)
        email_address = Column(String, nullable=False)
        user_id = Column(Integer, ForeignKey('users.id'))
    
        user = relationship(User, backref=backref('addresses', order_by=id))
    
        def __init__(self, email_address):
            self.email_address = email_address
    
        def __repr__(self):
            return "<Address('%s')>" % self.email_address
    
    
    
    metadata.create_all(engine)
    
    session.add_all([User('jim', 'Jim Gregson', 'secretword'),
                     User('john', 'John Smith', 'password'),
                     User('jane', 'Jane Doe', 'qweasdzxc'),
                     User('bob', 'Bob Johnson', '122765')])
    
    session.commit()
    
    for instance in session.query(User).order_by(User.id): print instance
    
    
    
    jack = User('jack', 'Jack Bean', 'gjffdd')
    print "jack.addresses: ", jack.addresses
    jack.addresses = [Address(email_address='jack@google.com'), Address(email_address='j25@yahoo.com')]
    print "jack.addresses: ", jack.addresses
    print "jack.addresses[1].user: ", jack.addresses[1].user
    
    session.add(jack)
    session.commit()
    
    Error below when 'session.commit()' is called;
    sqlalchemy.exc.OperationalError: (OperationalError) no such table: addresses u'INSERT INTO addresses (email_address, user_id) VALUES (?, ?)' ('jack@google.com', 5)
    

1 个答案:

答案 0 :(得分:4)

Base对象包含它自己的元数据实例,它会在定义实体时添加更多元数据。因此,当定义User类时,Base对象会实现这一点,并将User类的所有元数据添加到它自己的元数据实例(Base.metadata)。

在您的脚本中,您已创建自己的元数据实例(metadata = MetaData()),然后使用该空元数据创建表格(metadata.create_all(engine))。

请勿创建自己的元数据,而应使用基本元数据:

Base.metadata.create_all(engine)

修改

另一个注意事项:您可能会收到用户表的相同错误,但似乎您已经在我的回答“空”元数据中调用了用户表元数据。你不需要这样做;以你完成它的方式定义User表(定义“User”类)足以完成你所说的“users_table = Table(...)”时所做的一切。你基本上是以两种方式做同样的事情,而你真的只需要做一次。