Cookies op Tweakers

Tweakers maakt gebruik van cookies, onder andere om de website te analyseren, het gebruiksgemak te vergroten en advertenties te tonen. Door gebruik te maken van deze website, of door op 'Ga verder' te klikken, geef je toestemming voor het gebruik van cookies. Wil je meer informatie over cookies en hoe ze worden gebruikt, bekijk dan ons cookiebeleid.

Meer informatie
Toon posts:

[servoy][postgresql] Default value word niet overschreven

Pagina: 1
Acties:

Vraag


  • Dorgaldir
  • Registratie: september 2009
  • Laatst online: 28-01 10:33

Dorgaldir

Creature of the web

Topicstarter
Ik heb een postgresql table die er ongeveer zo uitziet, met een uuid function als default value voor de id.
code:
1
2
3
4
5
6
7
CREATE TABLE public.table
(
  id uuid NOT NULL DEFAULT functions.gen_random_uuid(),
  value_numeric numeric DEFAULT 0,
  value_text text,
  CONSTRAINT table_pkey PRIMARY KEY (id)
)

Als ik me niet vergis, en volgens https://www.postgresql.org/docs/9.3/static/ddl-default.html vergis ik me niet, worden default values overschreven indien die meegegeven worden.
code:
1
A column can be assigned a default value. When a new row is created and no values are specified for some of the columns, those columns will be filled with their respective default values.

[

Maar... Als ik dit doe:
code:
1
2
3
4
5
6
7
8
FS.newRecord( );
FS.id = CFS.id;
application.output("CFS " + CFS.id);
application.output("pre save FS " + FS.id);

databaseManager.saveData( FS );
databaseManager.refreshRecordFromDatabase(FS,1);
application.output("post save " + FS.id);

krijg ik:
code:
1
2
3
CFS AA3CF893-79F4-44AF-AE12-DE5DE7FACFE4
pre save FS 
post save 9635CCA4-7FEF-4FA3-8E62-76146516F2BF

Weet iemand waarom dit misgaat en hoe ik dit kan oplossen? Als workarround kan ik de id achteraf overschrijven, maar da's geen mooie coding en het zou dan op heel veel plaatsen aangepast moeten worden. Terwijl het volgens mij gewoon zou moeten werken...

Just me

Beste antwoord (via Dorgaldir op 09-01-2018 11:45)


  • DJMaze
  • Registratie: juni 2002
  • Niet online
Haal dan gewoon de DEFAULT weg en maak een BEFORE INSERT trigger met:
code:
1
IF NEW.ID IS NULL THEN NEW.ID = functions.gen_random_uuid()

Maak je niet druk, dat doet de compressor maar

Alle reacties


  • WannaKnow
  • Registratie: maart 2011
  • Laatst online: 07-04 11:52
Klopt niet wat ik zei :O

[Voor 84% gewijzigd door WannaKnow op 08-01-2018 13:03. Reden: Te snel gereageerd]


  • DJMaze
  • Registratie: juni 2002
  • Niet online
Kan je tonen welke query databaseManager.saveData() naar de server stuurt?

Maak je niet druk, dat doet de compressor maar


  • Dorgaldir
  • Registratie: september 2009
  • Laatst online: 28-01 10:33

Dorgaldir

Creature of the web

Topicstarter
quote:
DJMaze schreef op maandag 8 januari 2018 @ 15:47:
Kan je tonen welke query databaseManager.saveData() naar de server stuurt?
Ik vind niet direct hoe ik de query kan tonen die de saveData gebruikt... ik kan een getquery op de foundset doen, maar die geeft enkel de select query terug. Weet jij hoe ik die kan oproepen? Ben even in de documentatie aan het kijken geweest maar vind het niet.

Just me


  • DJMaze
  • Registratie: juni 2002
  • Niet online

Maak je niet druk, dat doet de compressor maar


  • CurlyMo
  • Registratie: februari 2011
  • Laatst online: 13:44

CurlyMo

www.pilight.org


SQL:
1
2
insert into public.table (value_text) values ('foo');
select * from public.table;

Werkt hier perfect:
code:
1
83d260bb-9c5a-4254-9d71-e8eb751f3b39   0   foo

Het ligt dus niet aan PostgreSQL

[Voor 8% gewijzigd door CurlyMo op 08-01-2018 17:18]

geen vragen via PM die ook op het forum gesteld kunnen worden.


  • RubenDJ
  • Registratie: februari 2000
  • Laatst online: 07-04 23:21

RubenDJ

Freude am fahren

Zo te zien stel je de FS.id (primary key) al via een andere waarde: CFS.id. Op dat moment schrijft Servoy dat nog niet naar de database, dat gebeurt pas bij de databaseManager.saveData(). Echter in PostgreSQL wordt die dan weer overschreven (of eigenlijk genegeerd) middels de default function. Dat is dus dubbelop en daar komt het verschil vandaan.

Als je wilt dat de database de sequences voor je uitkeert, zul je in Servoy de Sequence Type van je primary key op 'db identity' moeten zetten. Als Servoy namelijk niet op de hoogte is van de pk's zul je onherroepelijk tegen problemen aanlopen en kun je ook niet goed gebruik maken van de sterke caching van Servoy. Je kunt uuid's ook door Servoy laten uitkeren door de Sequence Type op 'uuid generator' te zetten, maar dan moet je de default function van de tabel(len) afhalen.

Deze regel is sowieso ook niet meer nodig :
code:
1
databaseManager.refreshRecordFromDatabase(FS,1);

[Voor 11% gewijzigd door RubenDJ op 08-01-2018 17:35]

De mooiste verbinding tussen 2 punten is een bocht | specs


  • Dorgaldir
  • Registratie: september 2009
  • Laatst online: 28-01 10:33

Dorgaldir

Creature of the web

Topicstarter
quote:
RubenDJ schreef op maandag 8 januari 2018 @ 17:33:
Zo te zien stel je de FS.id (primary key) al via een andere waarde: CFS.id. Op dat moment schrijft Servoy dat nog niet naar de database, dat gebeurt pas bij de databaseManager.saveData(). Echter in PostgreSQL wordt die dan weer overschreven (of eigenlijk genegeerd) middels de default function. Dat is dus dubbelop en daar komt het verschil vandaan.

Als je wilt dat de database de sequences voor je uitkeert, zul je in Servoy de Sequence Type van je primary key op 'db identity' moeten zetten. Als Servoy namelijk niet op de hoogte is van de pk's zul je onherroepelijk tegen problemen aanlopen en kun je ook niet goed gebruik maken van de sterke caching van Servoy. Je kunt uuid's ook door Servoy laten uitkeren door de Sequence Type op 'uuid generator' te zetten, maar dan moet je de default function van de tabel(len) afhalen.

Deze regel is sowieso ook niet meer nodig :
code:
1
databaseManager.refreshRecordFromDatabase(FS,1);

Ja het is de bedoeling dat deze key dezelfde waarde heeft als de key uit de andere foundset, het gaat namelijk om een conversie van data tussen twee databases, vandaar dat de primary key's hier hetzelfde zijn en deze dus gezet word vanuit die tweede foundset CFS.

Het is dus zo dat we Servoy opzich niet de keys willen laten genereren omdat er door andere applicaties ook gebruikt word gemaakt van dezelfde database, vandaar dat de key ingevuld word met een default value, want in de meeste gevallen zal bij het aanmaken van een record er gewoon een nieuwe key nodig zijn en we wilden dat dit voor alle verschillende applicaties hetzelfde is, vandaar de default value.
Alleen is het in sommige gevallen dus nodig dat keys manueel gezet moeten worden als het dus om een conversie gaat van oude naar nieuwe tabellen, en daar loopt het dus mis...

Just me


  • RubenDJ
  • Registratie: februari 2000
  • Laatst online: 07-04 23:21

RubenDJ

Freude am fahren

quote:
Dorgaldir schreef op maandag 8 januari 2018 @ 23:33:
[...]
Alleen is het in sommige gevallen dus nodig dat keys manueel gezet moeten worden als het dus om een conversie gaat van oude naar nieuwe tabellen, en daar loopt het dus mis...
In dat geval kun je denk ik het best ongeveer zo doen:
code:
1
2
3
4
5
FS.newRecord();
databaseManager.saveData(FS); // record insert

FS.id = CFS.id
databaseManager.saveData(FS); // record update

Of anders gewoon rawsql plugin gebruiken.

De mooiste verbinding tussen 2 punten is een bocht | specs


  • Dorgaldir
  • Registratie: september 2009
  • Laatst online: 28-01 10:33

Dorgaldir

Creature of the web

Topicstarter
quote:
RubenDJ schreef op dinsdag 9 januari 2018 @ 08:48:
[...]

In dat geval kun je denk ik het best ongeveer zo doen:
code:
1
2
3
4
5
FS.newRecord();
databaseManager.saveData(FS); // record insert

FS.id = CFS.id
databaseManager.saveData(FS); // record update

Of anders gewoon rawsql plugin gebruiken.
Die workarround had ik ook al gevonden, en opzich werkt dat inderdaad. Maar... er is spijtig genoeg een maar...
Omdat die tabellen in sync moeten gehouden worden met de oude tabellen (dit is tijdelijk nodig tot we het oude systeem helemaal hebben uitgefaseerd) zit er op die tabellen een trigger die een record aanmaakt bij elke wijziging in een sync tabel. En op basis van die tabel gaan we bijhouden welke records moeten geupdate, geinsert of gedelete worden.
Dit is de trigger:
SQL:
1
2
3
4
5
CREATE TRIGGER add_queue
    AFTER INSERT OR DELETE OR UPDATE 
    ON public.tabel
    FOR EACH ROW
    EXECUTE PROCEDURE sync_functions.add_queue();

In een ideale situatie, als we dus een insert kunnen doen met onmiddelijk de juiste key, dan gaat er één lijn aangemaakt worden, als die dan verwerkt word door de cronjob, dan gaat het systeem zien dat die key van die tweede INSERT in de nieuwe database, reeds in de oude database staat, zo kan hij zien dat het een INSERT is die genegeerd kan worden ipv terug gekopieerd.
Indien we het zo doen, zoals je voorstelt, dan gaan we 2 lijnen krijgen in die sync tabel, eentje met een key die niet voorkomt in de oude tabel, waardoor hij die niet gaat herkennen, en terug gaat willen overschrijven en zo creëer je een eindeloze loop van het kopiëren van dezelfde lijn van de ene naar de andere en terug...

Tenzij, ik een script maak dat na de eerste SaveData(FS) die lijn gaat verwijderen in de sync tabel... dan is dat probleem opgelost, maar je snapt dat ik liefst zo min mogelijk stappen heb en het gewoon van de eerste keer juist in de database wil hebben...

Just me


Acties:
  • Beste antwoord
  • 0Henk 'm!

  • DJMaze
  • Registratie: juni 2002
  • Niet online
Haal dan gewoon de DEFAULT weg en maak een BEFORE INSERT trigger met:
code:
1
IF NEW.ID IS NULL THEN NEW.ID = functions.gen_random_uuid()

Maak je niet druk, dat doet de compressor maar


  • Dorgaldir
  • Registratie: september 2009
  • Laatst online: 28-01 10:33

Dorgaldir

Creature of the web

Topicstarter
Even getest en op het eerste zicht lijkt dit te werken, nu nog wat verder uitwerken en degelijk testen maar ik denk hiermee wel op de goede weg te zitten :) thx!

Just me

Pagina: 1


Apple iPhone 11 Microsoft Xbox Series X LG OLED C9 Google Pixel 4 CES 2020 Samsung Galaxy S20 4G Sony PlayStation 5 Nintendo Switch Lite

'14 '15 '16 '17 2018

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2020 Hosting door True