GeoServer: configuring a primary key metadata table for pk assignment using a PostGIS store - primary-key

THE ISSUE
I am following directions in the GeoServer docs with respect to creating a primary key metadata table, but I am unable to assign the primary key of my geographic features (stored in a PostGIS store) using the value of an attribute with the same name in a WFS-t request.
Specifically, I am creating a UUID client-side (this is necessary), and then sending it as the 'uuid' attribute of the WFS-t request XML to GeoServer. Once in GeoServer's hands, I want that UUID to be inserted into the geometry table's primary key column, also named 'uuid'. What happens instead, is that GeoServer automatically creates its own primary key, something that looks like the following:
fid--46a202d5_15320520551_-7ffe
THE CONTEXT
Here is my geometry table SQL:
CREATE TABLE test_points (uuid VARCHAR(60) PRIMARY KEY NOT NULL);
ALTER TABLE test_points ADD COLUMN title VARCHAR(30) NOT NULL;
ALTER TABLE test_points ADD COLUMN body TEXT NOT NULL;
SELECT AddGeometryColumn('public', 'test_points', 'geometry', '4326', 'POINT', 2);
Here is my primary key metadata table SQL, basically same as in docs:
CREATE TABLE public.gt_pk_metadata_table (
table_schema VARCHAR(32) NOT NULL,
table_name VARCHAR(32) NOT NULL,
pk_column VARCHAR(32) NOT NULL,
pk_column_idx INTEGER,
pk_policy VARCHAR(32),
pk_sequence VARCHAR(64),
unique (table_schema, table_name, pk_column),
check (pk_policy in ('sequence', 'assigned', 'autoincrement'))
);
INSERT INTO gt_pk_metadata_table (
table_schema,
table_name,
pk_column,
pk_policy
) VALUES (
'public',
'test_points',
'uuid',
'assigned'
);
I have had the WFS-t insert operation working correctly (without primary key assignment), but here is a representative example of my WFS-t request XML, in case it helps:
<Transaction xmlns="http://www.opengis.net/wfs" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Insert>
<test_points xmlns="my points">
<geometry>
<Point xmlns="http://www.opengis.net/gml" srsName="EPSG:3857">
<pos>-11828783.001187595 4559315.863154193</pos>
</Point>
</geometry>
<uuid>18984168-27cc-4fc8-8dea-bfbd39c42b22</uuid>
<title>A Perfect Example</title>
<body>Here's my body.</body>
</test_points>
</Insert>
</Transaction>
In terms of my GeoServer configuration, on the configuration page of the data store I am using I have the "expose primary keys" flag enabled, and the value of the primary key metadata table parameter is left blank (see below for other values I have tried)
FAILED ATTEMPTS
Here is a list of other things I have tried:
Creating the geometry table without setting PRIMARY KEY
Creating the geometry table with primary key column of type UUID
Creating the geometry table in a schema other than 'public', keeping the primary key metadata table in the 'public' schema
Creating BOTH the geometry table and the public key metadata table in a schema other than 'public'
Altering the record in the primary key metadata table so that the value in the pk_column_idx column is 0
Altering the record in the primary key metadata table so that the value in the pk_column_idx column is 1
Disabling the "expose primary keys" flag in the store config
Changing the value of the "primary key metadata table" parameter in the store config to the schema qualified name of the metadata table
Changing the value of the "primary key metadata table" parameter in the store config to the NON-schema qualified name of the metadata table
After each of these changes I deleted the test_points layer and then republished it. Additionally, I have tried deleting and recreating the store a couple times.
As you can see, I'm getting sort of desperate. Any help would be very greatly appreciated!
UPDATE: GeoServer log of insertion
Great idea iant, I'm sure that may help! Here is an example of what is logged by GeoServer during an insertion. Besides the fact that idgen is set to GenerateNew, which I assume is an indication that GeoServer thinks it should generate a new pk, all looks well to me. But, this is my first project using GeoServer, so that may not mean much. A heads up: the UUID, title, body, and geometry are different from the above XML example.
2016-03-01 16:14:29,755 INFO [geoserver.gwc] - DataStoreChange:{/mypoints}test_points PreInsert
2016-03-01 16:14:29,760 INFO [geoserver.gwc] - DataStoreChange: {/mypoints}test_points PostInsert
2016-03-01 16:14:29,763 INFO [geoserver.wfs] -
Request: transaction
service = WFS
version = 1.1.0
baseUrl = http://127.0.0.1:8080/geoserver/
group[0] = wfs:insert=net.opengis.wfs.impl.InsertElementTypeImpl#5b886147 (feature: [SimpleFeatureImpl:test_points=[SimpleFeatureImpl.Attribute: uuid<uuid id=fid-4f745b22_1532fc9fb1c_-7ffa>=853596f8-9de1-477a-b287-f3cd114db90a, SimpleFeatureImpl.Attribute: title<title id=fid-4f745b22_1532fc9fb1c_-7ffa>=Another Test, SimpleFeatureImpl.Attribute: body<body id=fid-4f745b22_1532fc9fb1c_-7ffa>=For you!, SimpleFeatureImpl.Attribute: geometry<geometry id=fid-4f745b22_1532fc9fb1c_-7ffa>=POINT (-12044029.67283865 4265797.674539117)]], handle: null, idgen: <unset>, inputFormat: <unset>, srsName: null)
insert[0]:
feature[0] = SimpleFeatureImpl:test_points=[SimpleFeatureImpl.Attribute: uuid<uuid id=fid-4f745b22_1532fc9fb1c_-7ffa>=853596f8-9de1-477a-b287-f3cd114db90a, SimpleFeatureImpl.Attribute: title<title id=fid-4f745b22_1532fc9fb1c_-7ffa>=Another Test, SimpleFeatureImpl.Attribute: body<body id=fid-4f745b22_1532fc9fb1c_-7ffa>=For you!, SimpleFeatureImpl.Attribute: geometry<geometry id=fid-4f745b22_1532fc9fb1c_-7ffa>=POINT (-12044029.67283865 4265797.674539117)]
idgen = GenerateNew
inputFormat = text/xml; subtype=gml/3.1.1
releaseAction = ALL

Adding a fid="your_target_id" attribute to the feature and a idgen="UseExisting" attribute to the wfs:Insert allowed me to assign an uuid.
Here's the best documentation I could find on idgen. I'm unclear on its analogues in WFS 1.0.0 and 2.0.0.

Related

Why is the column not altering when I try to convert it to UUID?

I have a primary key column in my SQL table in PostgreSQL named "id". It is a "bigseries" column. I want to convert the column to a "UUID" column. It entered the below command in the terminal:
alter table people alter column id uuid;
and
alter table people alter column id uuid using (uuid_generate_v4());
but neither of them worked.
In both tries I got the error message
ERROR: syntax error at or near "uuid"
LINE 1: alter table people alter column id uuid using (uuid_generate...
What is the correct syntax?
First of all uuid_generate_v4() is a function which is provided by an extension called uuid-ossp. You should have install that extension by using;
CREATE EXTENSION uuid-ossp;
Postgresql 13 introduced a new function which does basically the same without installing extension. The function is called gen_random_uuid()
Suppose that we have a table like the one below;
CREATE TABLE people (
id bigserial primary key,
data text
);
The bigserial is not a real type. It's a macro which basically creates bigint column with default value and a sequence. The default value is next value of that sequence.
For your use case, to change data type, you first should drop the old default value. Then, alter the type and finally add new default value expression. Here is the sample:
ALTER TABLE people
ALTER id DROP DEFAULT,
ALTER id TYPE uuid using (gen_random_uuid() /* or uuid_generate_v4() */ ),
ALTER id SET DEFAULT gen_random_uuid() /* or uuid_generate_v4() */ ;
CREATE TABLE IF NOT EXISTS people (
id uuid NOT NULL CONSTRAINT people_pkey PRIMARY KEY,
address varchar,
city varchar(255),
country varchar(255),
email varchar(255),
phone varchar(255)
);
This is the correct syntax to create table in postgres SQL, it's better to do these constraints at beginning to avoid any error.
For using alter command you would do the following:
ALTER TABLE customer ADD COLUMN cid uuid PRIMARY KEY;
Most of errors that you could find while writing command either lower case or undefined correct the table name or column.

Postgres GENERATED AS IDENTITY column nullability

I want to create a table, which contains a nullable column having GENERATED BY DEFAULT AS IDENTITY option, therefore I run the following query:
CREATE TABLE my_table (
generated INTEGER NULL GENERATED BY DEFAULT AS IDENTITY,
data TEXT NOT NULL
);
But once I try to insert a row in the table, which generated field is null like this:
INSERT INTO my_table(generated, data) VALUES(NULL, "some data");
I get a null-constraint violation error.
However if I change the order of my_table.generated column properties:
CREATE TABLE my_table (
generated INTEGER GENERATED BY DEFAULT AS IDENTITY NULL,
data TEXT NOT NULL
);
It inserts rows, which generated field is NULL, without any issues.
Is this the expected behavior for the case?
Postgres developers told me this is a bug since identity columns weren't supposed to be nullable (see the patch file under the response).

Liquibase ignorable comments

Is there a way we can add comments in liquibase file which are not parsed by the program?
We are using the text format for the changes.sql and this is how it looks
--changeset Sapan.Parikh:MyUniqueAlphaNumericId5
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test11 (
id int primary key,
name varchar(255)
);
create table liqui_test9 (
id int primary key,
name varchar(255)
);
create table liqui_test10 (
id int primary key,
name varchar(255)
);
Our organization has been using similar change log for years and while migrating to Liquibase we want to be able to do two things.
Add dashes or hashes after each changeset.
And after every production build we add a comment at the end of the changes file.
For instance
--changeset Sapan.Parikh:MyUniqueAlphaNumericId5
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test11 (
id int primary key,
name varchar(255)
);
-----------------------------------------------------------------
--changeset Sapan.Parikh:MyUniqueAlphaNumericId4
--comment: Table created for liquibase testing purpose with non numeric id
--6:10 PM 11/10/2015
create table liqui_test12 (
id int primary key,
name varchar(255)
);
###------------------Build 10.0.1 Made-------------------
Now if we add just dashes- or # the luqibase task is breaking and DB upgrade does not happen. Is there a way to accommodate comments which are not parsed by liquibase engine?
You can just persist your comments and strip them right before executing liquibase
- can be done easily using sed

Cretae Domains Table In HSQL includes the metadata of Domains Sytem View

I want to create a table named Domains in HSQL. But when i try to do so it includes 29 columns although my table definition specifies just 5.There is a Domains System View and it seems it is including these columns also in my metadata.Because of this i am not able to insert anything in my db as those unwanted columns from Domains System View also contain some non-null values.
I tried creating schema but it is not what i need as my solution.
I need to override this Domains System View or stop the metadata from picking it.
Does anyone know how can we do it?
I am stuck at it for more than few days now.
CREATE TABLE IF NOT EXISTS Domains
(
domain_id INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
description VARCHAR(500) NOT NULL,
CREATED_BY VARCHAR(8) NOT NULL,
LAST_UPDATED_BY VARCHAR(8) NOT NULL,
PRIMARY KEY (domain_id)
);

Derby DB modify 'GENERATED' expression on column

I'm attempting to alter a Derby database that has a table like this:
CREATE TABLE sec_merch_categories (
category_id int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
packageName VARCHAR(100) NOT NULL,
name VARCHAR(100) NOT NULL,
primary key(category_id)
);
I'd like to change the category_id column to be:
category_id int NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
The only place I've seen that documents this is IBM's DB2, which advises dropping the expression, changing the integrity of the table, and adding the expression back. Is there anyway of doing this in Derby?
Thanks,
Andrew
You can create a new table with the schema you want (but a different name), then use INSERT INTO ... SELECT FROM ... to copy the data from the old table to the new table (or unload the old table and reload it into the new table using the copy-data system procedures), then use RENAME TABLE to rename the old table to an alternate name and rename the new table to its desired name.
And, as #a_horse_with_no_name indicated in the above comment, all of these steps are documented in the Derby documentation on the Apache website.