После официального руководства ORM, и я сталкиваюсь с ошибкой - PullRequest
2 голосов
/ 15 июля 2011

Просто наперед, я новичок в программировании в целом, так что, полагаю, мне не хватает чего-то простого.Я пытался следовать официальному учебнику здесь , и я в разделе Построение отношений .Он работает до последнего session.commit (), когда говорит, что нет таблицы адресов.Это то, что я думаю должен делать код:

  1. Address устанавливает таблицу.
  2. metadata.create_all (engine) создает таблицу в текущем сеансе.
  3. Я настроил нового пользователя 'jack', включая некоторые адреса.
  4. Я пытаюсь добавить 'jack', а затем зафиксировать.

Я не уверен, что делаюнеправильно, я был бы признателен за любую помощь.

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 Ответ

4 голосов
/ 15 июля 2011

Объект Base содержит свой собственный экземпляр метаданных, к которому он добавляет больше метаданных по мере того, как определяются ваши сущности.Итак, когда класс User определен, объект Base понимает это и добавляет все метаданные для класса User в свой собственный экземпляр метаданных (Base.metadata).

В своем сценарии вы создаливаш собственный экземпляр метаданных (metadata = MetaData()), а затем позже использовали эти пустые метаданные для создания ваших таблиц (metadata.create_all(engine)).

Не создавайте свои собственные метаданные, а используйте вместо них базовые:

Base.metadata.create_all(engine)

Редактировать:

Еще одно примечание: вы, вероятно, получили бы такую ​​же ошибку для таблицы пользователей, но похоже, что вы определили метаданные таблицы пользователей вчто я назвал в своем ответе «пустые» метаданные.Вам не нужно делать это;определение таблицы User так, как вы это сделали (определение класса «User»), достаточно для того, чтобы делать все, что вы делали, когда говорили «users_table = Table (...)».Вы в основном делаете одно и то же двумя способами, и вам действительно нужно сделать только одно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...