SQLAlchemy致力于关系

时间:2013-12-29 21:00:41

标签: sqlalchemy

我是SQLALchemy的新手并尝试理解关系,根据SQLAlchemy教程,我创建了2个表,用户和地址并创建了少量记录,

问题: 1.如何访问与特定地址相关的所有用户

例如:address1 = Address(email_address='jack@google.com'),我需要用户为address1对象,即;杰克,但不幸的是它显示为“无”。

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import Sequence
from sqlalchemy.orm import sessionmaker
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, backref

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    password = Column(String(12))


    def __repr__(self):
        return "<User(name='%s', fullname='%s', password='%s')>" % (
                                self.name, self.fullname, self.password)

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String(50),nullable=False)
    user_id = Column(Integer,ForeignKey('users.id'))

    user = relationship("User",backref = backref('addresses',order_by=id))

    def __repr__(self):
        return "<Address(email_address='%s'>"% self.email_address

engine = create_engine('mysql+mysqldb://scott:tiger@localhost/sakila')

print sqlalchemy.__version__

Base.metadata.create_all(engine)


print User.__table__

Session = sessionmaker(bind=engine)
session = Session()
session.query(Address).delete() 
session.query(User).delete()

ed_user = User(name='ed',fullname='Ed Jones',password='edpassword')
session.add(ed_user)

our_user = session.query(User).filter_by(name='ed').first()

print our_user
print our_user is ed_user

session.add_all([
     User(name='wendy', fullname='Wendy Williams', password='foobar'),
     User(name='mary', fullname='Mary Contrary', password='xxg527'),
     User(name='fred', fullname='Fred Flinstone', password='blah')])
session.commit()

print ed_user.id

for instance in session.query(User).order_by(User.id):
    print instance.name, instance.fullname

print "**** Start printing ****"
for name, fullname in session.query(User.name,User.fullname):
    print name, fullname

print "**** Start printing ****"                                             
for user in session.query(User).filter(User.name == 'ed'):
    print user.name                                             


jack = User(name='jack',fullname='Jack Bean',password='ggg')

print jack.addresses    

jack.addresses = [Address(email_address='jack@google.com'),Address(email_address='prem1pre@gmail.com')]

print jack.addresses[1].user

session.add(jack) 
session.commit()

address1 = Address(email_address='jack@google.com')
print address1.user 
# print Address.email_address

2 个答案:

答案 0 :(得分:0)

最后使用address1时,它是一个新实例,而不是从数据库中提取的实例。而是在数据库中查询地址。

addr = session.query(Address).filter_by(email='jack@google.com').one()
print addr.email, addr.user.name

答案 1 :(得分:0)

以下两个查询中的任何一个都可以完成这项任务:

# version-1: get all users which have at least one Address with given email_address
users = session.query(User).filter(User.addresses.any(Address.email_address == 'jack@google.com'))

# version-2: same result in the end, but
#  1) does not use sub-query; 
#  2) might return duplicate rows (on the database) 
#  in case a combination of (user_id, email_address) is 
#  not unique, but SA will handle this on ORM level and 
#  will not return duplicates
users = session.query(User).join(Address, User.addresses).filter(Address.email_address == 'jack@google.com')

for u in users:
    print u

我会安全地使用版本-2,但我也会在表Address(user_id, email_address)

中添加一个唯一约束