通过sqlalchemy查询对数据库执行多个操作?

时间:2015-12-08 04:19:33

标签: database python-2.7 flask sqlalchemy flask-sqlalchemy

我有一些sqlalchemy模型PersonCar及其连接表。我想在给定单个数据的情况下对数据库执行多个操作,但是我在构建有效查询时遇到了问题。以下是模型:

class Person(Model):
    id = Column(Integer, primary_key=True)
    email = Column(String, unique=True)
    cars = relationship('Car', 
               secondary=persons_cars, 
               lazy='dynamic', 
               backref=db.backref('persons', lazy='dynamic')
    )

class Car(Model):
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)


persons_cars = Table('persons_cars', 
     Column('person_id', Integer, ForeignKey('person.id'), primary_key=True),
     Column('car_id', Integer, ForeignKey('car.id'), primary_key=True)
)

如果我收到某人的某些数据,请从API中获取:

{ email: 'hello@blahstuff.com',
  cars: ["audi", "honda", "toyota", "ford"]
}

然后查询应该能够:

  • 通过电子邮件获取人员。如果未找到,请创建人员

  • 从汽车列表中,创建数据库中不存在的任何汽车。对于存在的汽车,请获取它们。

  • 如果此人尚未拥有汽车,则将所有汽车与人员关联。

  • 将任何不在列表中的人的汽车关联。

然后,如果有一些新信息出现,

{ email: 'hello@blahstuff.com',
  cars: ["scion"]
}

数据库将为此人和汽车执行必要的插入/更新/删除。

这是我写的非常天真的查询,这非常慢:

# fetch or create the person
person = Person.query.filter_by(email=data['email'])
if person.count() == 0:
    person = Person(email=data['email'])

for car_name in data['cars']:
    r = Car.query.filter_by(name=car_name)

    # Car exists in Database, append to Person if not associated
    if r.count() > 0 and person.cars.filter_by(name=car_name).count() == 0:
        person.cars.append(r.first())

    # Car doesn't exist, so create it and append to person
    if r.count() == 0:
        person.cars.append(Car(name=car_name))

# Remove any cars that this person doesn't have anymore
for car in person.cars:
    if not car.name in data['cars']:
        person.car.remove(car)

session.add(person)
session.commit()

如何才能提高效率?

1 个答案:

答案 0 :(得分:0)

如果你的persons_cars表有关于人员和汽车组合的唯一索引,那么两个明显的改进就是检查.first()是否存在而不是计数,并使用try-catch子句进行完整性错误而不是探测对他们事先。