Was Sie ursprünglich hatten, war eine korrekte Syntax - für Tabellen , nicht für Schemas . Da Sie keine Tabelle hatten (in der Fehlermeldung als "Beziehung" bezeichnet), wurde der nicht gefundene Fehler ausgegeben.
Ich sehe, dass Sie dies bereits bemerkt haben - ich glaube, es gibt keinen besseren Weg zu lernen, als unsere eigenen Fehler zu beheben;)
Aber es gibt noch etwas mehr. Was Sie oben tun, ist einerseits zu viel und andererseits nicht genug.
Führen Sie das Skript aus, Sie
- Erstellen Sie ein Schema
- eine Rolle erstellen
- gewähren
SELECT
auf alle Tabellen in dem Schema in (1) auf diese neue role_ erstellt
- und schließlich gewähren Sie der neuen Rolle alle Berechtigungen (
CREATE
und USAGE
) für das neue Schema
Das Problem liegt in Punkt (3.) Sie haben Berechtigungen für Tabellen in gewährt replays
- aber es gibt dort keine Tabellen! Möglicherweise gibt es in Zukunft einige, aber zu diesem Zeitpunkt ist das Schema vollständig leer. Auf diese Weise macht das GRANT
in (3.) nichts - auf diese Weise tun Sie zu viel.
Aber was ist mit den zukünftigen Tischen?
Es gibt einen Befehl, um sie abzudecken : ALTER DEFAULT PRIVILEGES
. Dies gilt nicht nur für Tabellen, sondern auch für:
Derzeit [ab 9.4] können nur die Berechtigungen für Tabellen (einschließlich Ansichten und Fremdtabellen), Sequenzen, Funktionen und Typen (einschließlich Domänen) geändert werden.
Es gibt auch eine wichtige Einschränkung:
Sie können die Standardberechtigungen nur für Objekte ändern, die von Ihnen selbst oder von Rollen, denen Sie angehören, erstellt werden.
Dies bedeutet, dass eine Tabelle, die von erstellt wurde alice
, von der weder Sie noch eine Rolle als Sie Mitglied sind (kann beispielsweise durch Verwendung von \du
in überprüft werden psql
), nicht die vorgeschriebenen Zugriffsrechte erhält. Die optionale FOR ROLE
Klausel wird verwendet, um die Rolle des Tabellenerstellers anzugeben, in der Sie Mitglied sind. In vielen Fällen bedeutet dies, dass es eine gute Idee ist, alle Datenbankobjekte mit derselben Rolle zu erstellen mydatabase_owner
.
Ein kleines Beispiel, um dies bei der Arbeit zu zeigen:
CREATE ROLE test_owner; -- cannot log in
CREATE SCHEMA replays AUTHORIZATION test_owner;
GRANT ALL ON SCHEMA replays TO test_owner;
SET ROLE TO test_owner; -- here we change the context,
-- so that the next statement is issued as the owner role
ALTER DEFAULT PRIVILEGES IN SCHEMA replays GRANT SELECT ON TABLES TO alice;
CREATE TABLE replays.replayer (r_id serial PRIMARY KEY);
RESET ROLE; -- changing the context back to the original role
CREATE TABLE replays.replay_event (re_id serial PRIMARY KEY);
-- and now compare the two
\dp replays.replayer
Access privileges
Schema │ Name │ Type │ Access privileges │ Column access privileges
─────────┼──────────┼───────┼───────────────────────────────┼──────────────────────────
replays │ replayer │ table │ alice=r/test_owner ↵│
│ │ │ test_owner=arwdDxt/test_owner │
\dp replays.replay_event
Access privileges
Schema │ Name │ Type │ Access privileges │ Column access privileges
─────────┼──────────────┼───────┼───────────────────┼──────────────────────────
replays │ replay_event │ table │ │
Wie Sie sehen können, alice
hat keine explizite Rechte für die letztere Tabelle. (In diesem Fall kann sie immer noch SELECT
vom Tisch, weil sie Mitglied der public
Pseudorole ist, aber ich wollte das Beispiel nicht durch Widerruf der Rechte von überladen public
.)