SQLAlchemy: выбор из нескольких таблиц - PullRequest
4 голосов
/ 17 июня 2010

Я хотел оптимизировать свой запрос к базе данных:

link_list = select(
    columns=[link_table.c.rating, link_table.c.url, link_table.c.donations_in],
    whereclause=and_(
        not_(link_table.c.id.in_(
            select(
                columns=[request_table.c.recipient],
                whereclause=request_table.c.donator==donator.id
            ).as_scalar()
        )),
        link_table.c.id!=donator.id,
    ),
    limit=20,
).execute().fetchall()

и попытался объединить эти два выбора в одном запросе:

link_list = select(
    columns=[link_table.c.rating, link_table.c.url, link_table.c.donations_in],
    whereclause=and_(
        link_table.c.active==True,
        link_table.c.id!=donator.id,
        request_table.c.donator==donator.id,
        link_table.c.id!=request_table.c.recipient,
    ),
    limit=20,
    order_by=[link_table.c.rating.desc()]
).execute().fetchall()

схема базы данных выглядит следующим образом:

link_table = Table('links', metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('url', Unicode(250), index=True, unique=True),
    Column('registration_date', DateTime),
    Column('donations_in', Integer),
    Column('active', Boolean),
)
request_table = Table('requests', metadata,
    Column('id', Integer, primary_key=True, autoincrement=True),
    Column('recipient', Integer, ForeignKey('links.id')),
    Column('donator', Integer, ForeignKey('links.id')),
    Column('date', DateTime),
)

В request_table есть несколько ссылок (donator), указывающих на одну ссылку в link_table. Я хочу получить ссылки из link_table, которые еще не "запрошены".

Но это не работает. Это действительно возможно, что я пытаюсь сделать? Если да, то как бы вы это сделали?

Большое спасибо заранее!

Ответы [ 2 ]

1 голос
/ 01 августа 2011

Возможно, вы ищете SQL NOT EXISTS конструкцию:

http://www.sqlalchemy.org/docs/orm/tutorial.html#using-exists

0 голосов
/ 01 августа 2011

Обман ответ Масиды :

Во-первых, оригинальный запрос:

>>> print select(
...     columns=[link_table.c.url, link_table.c.donations_in],
...     whereclause=and_(
...         not_(link_table.c.id.in_(
...             select(
...                 columns=[request_table.c.recipient],
...                 whereclause=request_table.c.donator==5
...             ).as_scalar()
...         )),
...         link_table.c.id!=5,
...     ),
...     limit=20,
... )
SELECT links.url, links.donations_in 
FROM links 
WHERE links.id NOT IN (SELECT requests.recipient 
FROM requests 
WHERE requests.donator = :donator_1) AND links.id != :id_1 
 LIMIT 20

И переписано с точки зрения существования ():

>>> print select(
...     columns=[link_table.c.url, link_table.c.donations_in],
...     whereclause=and_(
...     not_(exists().where(request_table.c.donator==5)),
...     #    ^^^^^^^^^^^^^^
...         link_table.c.id!=5,
...     ),
...     limit=20,
... )
SELECT links.url, links.donations_in 
FROM links 
WHERE NOT (EXISTS (SELECT * 
FROM requests 
WHERE requests.donator = :donator_1)) AND links.id != :id_1 
 LIMIT 20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...