web application cannot see tables in new postgresql schema - postgresql

I moved some tables in my postgresql (8.2) database to a new schema.
at first, my "user" could not see the tables in the new schema, but I used set search_path to tell it to look in this new schema
I access these tables with a simple web application that uses hibernate. At first, my web application, which uses the "user" user, could not see the tables either, even after I set the search_path. I eventually set the default-schema in the hibernate config file and it worked, but I understand from what I've read that I should not have to set this property? I have a few JDBC queries in this app that still can't see the tables in the new schema.
I've browsed through the postgresql docs and can't find the cause of my problems. Is there something simple I'm missing?

SET search_path is not persisted. It is only valid for the current session.
You need to use ALTER USER to make that change permanently, but you don't need special privileges to change the user you are logged in with (i.e. "yourself")

Related

Append only data in phoenix, ecto and postgres

One of my models in Phoenix application has append-only semantics. There will be events that can be created, but should never be updated by the application (read only after creation).
Is there a postgres mechanism to enforce such thing on a table?
How should I define my migration to use it?
You can set the permissions on the table to allow INSERT and SELECT but not, for example, UPDATE or DELETE for the role that is used to access the data. This way there is no possibility to alter the data.
More information on permissions.

Automatically allow access to tables in postgres from a user

I have a Postgresql database for a web application. The database is owned by a particular user on the system, let's say foouser. As the owner, this user has full permissions on the database.
The server also has another user, let's say webappuser, which is the user under which the application server runs. Instead of specifying a username and password in the web application's config file, I want to use "peer" authentication. I have gotten the authentication to work properly, but I ran into the following issue.
When I created the webappuser role in Postgresql, I granted it LOGIN permission as well as GRANT ALL ON DATABASE foo TO webappuser; and within the database GRANT ALL ON SCHEMA public TO webappuser;.
The issue that I am having is with the table permissions. Unlike MySQL which allows access by default to all tables if you have access to the database (a reasonable assumption in my opinion), Postgresql denies access to all of the tables even though permission has been given on the schema and the database. In order to get around this, I have to explicitly grant permissions on all new tables, views, procedures, etc. that I create using GRANT ALL ON TABLE table_name TO webappuser; (and similarly for views, etc.).
It ends up that any time I run a database migration, I have to add the permissions to the database for the new tables that were created. The problem is that I can't add this permission information to the migrations themselves because developer machines don't have that additional user. In any case, that really looks like the wrong way of doing things.
How can I allow access to the database tables from this additional user without needing manual intervention every time a table, view, procedure, etc. is created?
BONUS POINTS: Is there a way to restrict the user's permission to only CRUD operations instead of full permissions and still do the whole thing automatically?
Without experience with the specifics of Laravel migrations: When you do migrations on the same server there should be no problem, so long as the permissions are also migrated, because the webappuser is available cluster-wide.
When migrating to a different server you need to create the user on that new server and set the permissions for all migrated objects. You basically have two ways to do that.
The first is to set default privileges on the tables in the schema before you migrate or GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA sch_name TO webappuser after the migration. Default privileges are set with:
ALTER DEFAULT PRIVILEGES IN SCHEMA sch_name
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO webappuser;
Both commands are fully SQL-standard compliant so you should have no problems across compliant architectures.
Keep in mind that any other tables created in the same schema will also have privileges set for webappuser. Setting privileges this way for an "untrusted" user (the person using the web application) is not recommended in a production environment because of potential privilege leaks; in a development environment it may be acceptable.
The second - which I would favour personally - is to write a stored procedure that sets the appropriate permissions. Do the migration, run the stored procedure once and you should be up-and-running. This gives you more control over the permission granting. The procedure could be something like:
CREATE FUNCTION grant_webapp_privileges() RETURNS void AS $$
-- Create the webappuser, if necessary
CREATE ROLE webappuser LOGIN;
-- Grant privileges on all required objects
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLE table1 TO webappuser;
...
$$ LANGUAGE SQL;
On the master database you simply need to keep the stored procedure up-to-date when you create or drop new relations. If Laravel supports insertion of code blocks not in the schema you are migrating, you can make the above procedure an anonymous code block that gets executed after the migration.
(As an aside, I NEVER give webappuser-like roles CRUD access. Instead I always provide access through views that hide some of the underlying data model specifics, such as a person having an address, contact_information and other details; the view serves it all up in one big row. That way you can easily change the underlying relations and update the view, rather than having to tweak your web application. Same principle really as OOP and easier to manage privileges.)

Netbeans 7.4: Creating entity classes (JPA) from java db embedded database

I am using Netbeans 7.4 to build my application. And also, I am using embedded java db. Now, I want to generate my JPA entities from my database from my database.
But, when I
rightclick my package -> New -> Entity classes from database, select my database, Available Tables is not showing up even a single one of the tables inside ANK schema.
One more strange thing I noticed is when I connect my db from Netbeans services tab, two schema options appear. First, APP in bold, second Other schemas. Schema APP don't have any tables. The tables are in ANK schema in Other schemas.
Can anybody tell me where I could have gone wrong?
I don't even know if I should be using java db, or I should go for pretty appealing h2, HSQL or some matured db like mysql.
The Nebeans interface to Derby is a bit tricky.
When creating a new database, only the APP schema is created by default (except for the SYS* schemas).
When you connect to the database without specifying a username, your default schema becomes APP
When connecting as user john, your default schema becomes john, BUT the schema john is NOT created, until you create an SQL object in it.
This means that if you create an initial connection to Derby in Netbeans as user john, you cannot choose john as the schema for the connection in the pull-down menu, because it has not been created yet. If you then choose another schema, create your table, disconnect and then create another connection you will be able to choose john as your schema, and you will find the table you created with the previous connection.
Even though you chose a different schema in the pull-down menu for the first connection, a schema with the same name as the username you connect as is created and set as default before starting to execute the create table statement.

libpq code to create, list and delete databases (C++/VC++, PostgreSQL)

I am new to the PostgreSQL database. What my visual c++ application needs to do is to create multiple tables and add/retrieve data from them.
Each session of my application should create a new and distinct database. I can use the current date and time for a unique database name.
There should also be an option to delete all the databases.
I have worked out how to connect to a database, create tables, and add data to tables. I am not sure how to make a new database for each run or how to retrieve number and name of databases if user want to clear all databases.
Please help.
See the libpq examples in the documentation. The example program shows you how to list databases, and in general how to execute commands against the database. The example code there is trivial to adapt to creating and dropping databases.
Creating a database is a simple CREATE DATABASE SQL statement, same as any other libpq operation. You must connect to a temporary database (usually template1) to issue the CREATE DATABASE, then disconnect and make a new connection to the database you just created.
Rather than creating new databases, consider creating new schema instead. Much less hassle, since all you need to do is change the search_path or prefix your table references, you don't have to disconnect and reconnect to change schemas. See the documentation on schemas.
I question the wisdom of your design, though. It is rarely a good idea for applications to be creating and dropping databases (or tables, except temporary tables) as a normal part of their operation. Maybe if you elaborated on why you want to do this, we can come up with solutions that may be easier and/or perform better than your current approach.

Seamlessly updating a postgres database - schemas, rename, how?

Actually a simple question, but I wasn't able to find any good conclusive answer.
Assuming a production database foo_prd, and a newer version of the same foo_new (on the same server) that is supposed to replace the old one. What is the cleanest way to seamlessly switch from _prd to _new?
RENAME-ing the databases would require to disconnect the current users via their pid. That would take down some requests, and new users might connect during the process. I was thinking of creating the tables of the new database as different SCHEMA and then change the search_path, e.g. from "$user",prd to "$user",new,prd.
What could possibly go wrong? Do you have any better suggestions? Am I taking the wrong approach altogether?
Do as you suggest: create the tables of the new database as different schema and then change the search_path.
But also create a user with the same name as the new schema and test everything before changing the search_path by logging in as this user with each of your apps - the new schema will be first in that user's search_path by default because the name matches.
Finally, take care when you come to drop the old schema - I suggest renaming first in case anything refers to it's objects using a qualified reference (eg prd.table or prd.function). After a few days/weeks it can then be dropped with confidence.
I would version my schema, and change my app to point to the new schema when ready.