У меня есть таблицы, созданные Django в базе данных PostgreSQL 8.4, где одна таблица «расширяет» другую. Одна таблица (FooPayment
) имеет первичный ключ, который ссылается на другую таблицу (Payment
). В SQL это выглядит так:
CREATE TABLE foo.payments_payment
(
id integer NOT NULL DEFAULT nextval('payments_payment_id_seq'::regclass),
user_id integer NOT NULL,
...
CONSTRAINT payments_payment_pkey PRIMARY KEY (id),
CONSTRAINT payments_payment_user_id_fkey FOREIGN KEY (user_id)
REFERENCES auth.auth_user (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)
CREATE TABLE foo.payments_foopayment
(
payment_ptr_id integer NOT NULL,
...
CONSTRAINT payments_foopayment_pkey PRIMARY KEY (payment_ptr_id),
CONSTRAINT payments_foopayment_payment_ptr_id_fkey FOREIGN KEY (payment_ptr_id)
REFERENCES foo.payments_payment (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED,
...
)
Однако я не использую Django ORM по разным причинам, и я пытаюсь получить доступ к таблицам из SQLAlchemy (я использую версию 0.6.6, как было установлено с pip
):
# Base = declarative_base()
...
class Payment(Base):
__tablename__ = 'payments_payment'
__table_args__ = {'schema': 'foo', 'autoload': True}
user = relation(User, backref='payments')
class FooPayment(Payment):
__tablename__ = 'payments_foopayment'
__table_args__ = {'schema': 'foo', 'autoload': True}
Когда я делаю это как суперпользователь, все работает. Когда я подключаюсь как пользователь с низкими привилегиями, я получаю исключение:
Traceback (most recent call last):
File "./test.py", line 3, in <module>
from foos import models
File "./foos/models.py", line 127, in <module>
class FooPayment(Payment):
File "lib/python2.6/site-packages/sqlalchemy/ext/declarative.py", line 1167, in __init__
_as_declarative(cls, classname, cls.__dict__)
File "lib/python2.6/site-packages/sqlalchemy/ext/declarative.py", line 1099, in _as_declarative
ignore_nonexistent_tables=True)
File "lib/python2.6/site-packages/sqlalchemy/sql/util.py", line 260, in join_condition
"between '%s' and '%s'.%s" % (a.description, b.description, hint))
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'payments_payment' and 'payments_foopayment'.
Когда я подключаюсь как этот пользователь с низкими привилегиями с PgAdmin3, я вижу взаимосвязь в GUI. Я также вижу это с этим утверждением, SQLAlchemy выдает себя:
SELECT conname, pg_catalog.pg_get_constraintdef(oid, true) as condef
FROM pg_catalog.pg_constraint r
WHERE r.conrelid = 16234 AND r.contype = 'f'
ORDER BY 1
Правильно возвращает строку, содержащую
"payments_foopayment_payment_ptr_id_fkey"; "FOREIGN KEY (payment_ptr_id) REFERENCES payments_payment(id) DEFERRABLE INITIALLY DEFERRED"
Что касается разрешений базы данных, то payments_payment
и payments_foopayment
имеют значения GRANT
ed SELECT
и UPDATE
. Я пытался временно предоставить все разрешения для них, но безуспешно. Если это имеет значение, последовательность payments_payment_id_seq
равна GRANT
ed для SELECT
и USAGE
. Очевидно, схема foo
является GRANT
ed для USAGE
.
Как мне определить отношение вручную в Python или сделать что-то на стороне БД, чтобы интроспекция работала для непривилегированного пользователя?
Также очень приветствуются советы по отладке проблемы, так как я полностью заблудился во внутренностях SA.