BŁĄD: odmowa zezwolenia na sekwencję city_id_seq przy użyciu Postgres

201

Jestem nowy w postgres (i ogólnie w systemach informacyjnych baz danych). Uruchomiłem następujący skrypt SQL w mojej bazie danych:

create table cities (
id serial primary key,
name text not null
);

create table reports (
id serial primary key,
cityid integer not null references cities(id),
reportdate date not null,
reporttext text not null
);

create user www with password 'www';

grant select on cities to www;
grant insert on cities to www;
grant delete on cities to www;

grant select on reports to www;
grant insert on reports to www;
grant delete on reports to www;

grant select on cities_id_seq to www;
grant insert on cities_id_seq to www;
grant delete on cities_id_seq to www;

grant select on reports_id_seq to www;
grant insert on reports_id_seq to www;
grant delete on reports_id_seq to www;

Gdy jako użytkownik www próbuje:

insert into cities (name) values ('London');

Otrzymuję następujący błąd:

ERROR: permission denied for sequence cities_id_seq

Rozumiem, że problem leży w typie seryjnym. Dlatego udzielam prawa do wyboru, wstawiania i usuwania * _id_seq www. To jednak nie rozwiązuje mojego problemu. czego mi brakuje?

Vampnik
źródło
2
Przyznanie wstawienia / usunięcia sekwencji nie ma dla mnie sensu. Dziwi mnie, że to w ogóle działa.
a_horse_w_no_name

Odpowiedzi:

359

Od wersji PostgreSQL 8.2 musisz używać:

GRANT USAGE, SELECT ON SEQUENCE cities_id_seq TO www;

UŻYTKOWANIE DOTACJI - W przypadku sekwencji uprawnienie to umożliwia korzystanie z funkcji currval i nextval.

Jak wskazał @epic_fil w komentarzach, możesz udzielić uprawnień do wszystkich sekwencji w schemacie za pomocą:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
kupson
źródło
52
Do Twojej wiadomości, obsługiwana jest również składnia „.. NA WSZYSTKICH SEKWENCJACH W SCHEMIE nazwa_schematu”.
epic_fil
5
Ciekawy. Zrobiłam GRANT na stole, w którym znajduje się moja sekwencja, ale nie wydaje się, żeby to obejmowało sekwencję. Wydaje się to również bardzo przez system operacyjny.
Kinnard Hockenhull
41
Jak to jest prawdziwe? Kiedy kiedykolwiek chciałbym zezwolić użytkownikowi na wstawianie danych do tabeli, ale NIE chcę pozwolić mu na korzystanie z faktu, że jedna z kolumn jest automatycznie zwiększana?
Brett Widmeier,
5
Jest SELECTkonieczne? Nie powinien USAGEpokrywać tego, co jest potrzebne?
Tᴀʀᴇǫ Mᴀʜᴍᴏᴏᴅ,
6
@BrettWidmeier Dokładnie. Zdumiewa mnie to, jak deweloperzy tolerują tego rodzaju rzeczy. To tak, jakby ludzie chcieli wędrować po Internecie i czytać bezdenne wątki StackOverflow, próbując naprawić rzeczy, które powinny działać od razu po wyjęciu z pudełka.
milosmns
67

Ponieważ @Phil ma komentarz, który otrzymuje wiele pozytywnych opinii, które mogą nie zostać zauważone, używam jego składni, aby dodać odpowiedź, która przyzna użytkownikowi uprawnienia do wszystkich sekwencji w schemacie (zakładając, że twój schemat jest domyślnym „publicznym” )

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public to www;
Tom Gerken
źródło
2
Zauważ, że działa to tylko w PostgreSQL 9.0 i nowszych wersjach. Aby osiągnąć to samo w 8, możesz zrobić coś takiego: WYBIERZ „UŻYTKOWANIE DOTACJI, WYBIERZ” || quote_ident (schemaname) || „.” || quote_ident (zmiana nazwy) || „TO www;” OD pg_statio_all_sequences GDZIE schemaname = 'public'; - Tom Gerken 2 dni temu
Tom Gerken
39

@Tom_Gerken, @epic_fil i @kupson są całkiem poprawne ze swoimi instrukcjami, aby dać uprawnienia do pracy z istniejącymi sekwencjami. Jednak użytkownik NIE uzyska praw dostępu do sekwencji utworzonych w przyszłości. Aby to zrobić, musisz połączyć instrukcję GRANT z instrukcją ALTER DEFAULT PRIVILEGES, na przykład:

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO www;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
    GRANT USAGE, SELECT ON SEQUENCES TO www;

Oczywiście działa to tylko na PostgreSQL 9+.

Będzie to dołączać do istniejących domyślnych uprawnień, a nie nadpisywać ich, więc pod tym względem jest całkiem bezpieczne.

Asfand Qazi
źródło
-2

Wykonaj następujące polecenie w postgres.

zaloguj się do postgres:

sudo su postgres;

psql nazwa_db;

UTWÓRZ SEKWENCJĘ public.cities_id_seq INCREMENT 1 MINVALUE
0 MAXVALUE
1
START 1 CACHE 1; ALTER TABLE public.cities_id_seq WŁAŚCICIEL DO pgowner;

pgowner będzie użytkownikiem bazy danych.

Shreeram
źródło