У меня есть созданные 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, я вижу взаимосвязь в графическом интерфейсе. Я также вижу это с помощью этого оператора, 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.