Kann man die DB-Collation beim Upsize angeben?
Moderator: Moderatoren
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Kann man die DB-Collation beim Upsize angeben?
Damit String-Indexe sich so wie gewohnt verhalten (z.B., dass Leerzeichen vor Ziffern in der Reihenfolge stehen und nicht andersrum), muss die Postgres-Datenbank mit Collation "C.UTF-8" statt dem Default (z.B. "de_DE.UTF-8") angelegt werden.
Weißt jemand, ob dies irgendwie in der Upsize-datei festgelegt werden kann?
Weißt jemand, ob dies irgendwie in der Upsize-datei festgelegt werden kann?
Viele Grüße,
David
David
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Das ist eher eine Einstellung im Server. Geh mal in PgAdmin auf die Properties Deiner Datenbank, da gibt es den Bereich "Definition", in dem Du Encoding, Collation und Character Type einstellen kannst.
Herzlich,
Tom
Tom
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Hallo Tom,
ach, wenn es so einfach wäre!
Die Collation lässt sich aber dort nur anzeigen, nicht ändern.
Wenn eine Postgres-Datenbank angelegt wird, kann die Collation angegeben werden, aber danach ist sie für alle Zeiten festgelegt.
Derzeit kann ich das Problem nur umgehen in dem ich das Upsize machen, dann ein Backup, eine neue Datenbank mit der richtigen Collation anlege, das Backup dort einspiele und schließlich die "geupsizete" Datenbank lösche.
Wenn Upsize erlauben würde, die Collation anzugeben (oder vielleicht eine existierende, leere Datenbank zu benutzen anstatt eine neue anzugeben), dann bliebe mir das mit dem Backup erspart.
Trotzdem Danke für Deine Antwort!
ach, wenn es so einfach wäre!
Die Collation lässt sich aber dort nur anzeigen, nicht ändern.
Wenn eine Postgres-Datenbank angelegt wird, kann die Collation angegeben werden, aber danach ist sie für alle Zeiten festgelegt.
Derzeit kann ich das Problem nur umgehen in dem ich das Upsize machen, dann ein Backup, eine neue Datenbank mit der richtigen Collation anlege, das Backup dort einspiele und schließlich die "geupsizete" Datenbank lösche.
Wenn Upsize erlauben würde, die Collation anzugeben (oder vielleicht eine existierende, leere Datenbank zu benutzen anstatt eine neue anzugeben), dann bliebe mir das mit dem Backup erspart.
Trotzdem Danke für Deine Antwort!
Viele Grüße,
David
David
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
...anstatt eine neue anzulegen...
Viele Grüße,
David
David
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Ja, man kann das nur beim Anlegen der Datenbank machen, und auch nur im Server selbst. Von außen habe ich noch keinen Weg gefunden.
Herzlich,
Tom
Tom
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Ich habe vor eine Weile unseren Mitarbeiter, der derzeit die Rolle des Systemadministrators spielen muss, darum gebeten, die Default-Einstellung für Collation in der Postgres-Server-Installation zu ändern.
Leider hat er das nicht hingekriegt, obwohl er viel mehr von Linux versteht als ich.
Es bleibt mir wahrscheinlich nur übrig, Alaska zu fragen, ob vielleicht doch Upsize mehr kann als dokumentiert, oder bei dem Backup-Workaround zu bleiben.
Leider hat er das nicht hingekriegt, obwohl er viel mehr von Linux versteht als ich.
Es bleibt mir wahrscheinlich nur übrig, Alaska zu fragen, ob vielleicht doch Upsize mehr kann als dokumentiert, oder bei dem Backup-Workaround zu bleiben.
Viele Grüße,
David
David
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Oh, da interessiert mich die Antwort auch!
Herzlich,
Tom
Tom
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Folgende Dinge sollten auch irgendwo erwähnt werden:
- DBFs, die durch das Upsizing gehen sollen, dürfen keine Feldnamen enthalten, die SQL-Keywords sind (ich bin z.B. bei "AS" und "DO" gestolpert).
- DBFs, die durch das Upsizing gehen sollen, sollten ausschließlich Dateinamen haben, die mit Buchstaben beginnen. Ziffern und Sonderzeichen killen das Upsizing.
Der IUpsizeLogger könnte auch mal dokumentiert werden, ich habe mir zwei Klassen drumherum gebaut, aber wirklich transparent ist nicht, was der macht (etwa die Methode 'Progress'). Das gilt auch für die möglichen Meldungen von DbfUpsize(), die es, soweit ich das beurteilen kann, nur auf englisch gibt.
- DBFs, die durch das Upsizing gehen sollen, dürfen keine Feldnamen enthalten, die SQL-Keywords sind (ich bin z.B. bei "AS" und "DO" gestolpert).
- DBFs, die durch das Upsizing gehen sollen, sollten ausschließlich Dateinamen haben, die mit Buchstaben beginnen. Ziffern und Sonderzeichen killen das Upsizing.
Der IUpsizeLogger könnte auch mal dokumentiert werden, ich habe mir zwei Klassen drumherum gebaut, aber wirklich transparent ist nicht, was der macht (etwa die Methode 'Progress'). Das gilt auch für die möglichen Meldungen von DbfUpsize(), die es, soweit ich das beurteilen kann, nur auf englisch gibt.
Herzlich,
Tom
Tom
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Ja, ich bin über USER als Tabellenname und Feldname gestolpert.
Dafür habe ich aber Verständnis - ich möchte eigentlich lieber keine SQL-Keywords als Namen benutzen, selbst wenn es vielleicht mit Hochkommas theoretisch möglich wäre.
Es kostete zwar Arbeit, USER in BENUTZER zu ändern, ist aber sauberer.
Dafür habe ich aber Verständnis - ich möchte eigentlich lieber keine SQL-Keywords als Namen benutzen, selbst wenn es vielleicht mit Hochkommas theoretisch möglich wäre.
Es kostete zwar Arbeit, USER in BENUTZER zu ändern, ist aber sauberer.
Viele Grüße,
David
David
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
...und mit englischen Meldungen kann ich auch gut leben.
Viele Grüße,
David
David
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Es gibt ja die Möglichkeit, beim Upsizing die Feldnamen zu wechseln (deferred/rename), wenn man das weiß. Das machen wir auch. Und obwohl Alaska davon abrät, DBF weiter zu unterstützen, wenn man die PGDBE im ISAM-Modus verwendet, tun wir das - und unterstützen dann die übersetzten und die alten Feldnamen. Ist ein bisschen Arbeit, funzt aber.
Herzlich,
Tom
Tom
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Wir übersetzen im Logger. Manch ein Kunde oder Kunden-ITler macht das selbst...und mit englischen Meldungen kann ich auch gut leben.
Herzlich,
Tom
Tom
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Sorry Tom, da es bei mir nur um ein internes IT-System und kein Verkaufsprodukt handelt, habe ich das Problem mit den Meldungen nicht, aber jetzt verstehe ich warum es für Dich relevant ist.
Viele Grüße,
David
David
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Alaska Support hat wie folgt geantwortet:
Leider unterstützt die PGDBE die Angabe einer Collation aktuell noch nicht. Die Möglichkeit, die gewünschte Collation pro Index vorgeben zu können, steht aber bereits auf unserem Plan!
Als Work-Around für das Backup-Thema lässt sich eventuell ein Postgres-Feature nutzen; SQL-Indexe "erben" nämlich die Collation von der zugeordneten Column. Per default ist das die Collation der Datenbank. Es könnte aber auch mit Hilfe eines ALTER TABLE ALTER COLUMN .. COLLATION ..-Statements eine andere sein. Mit anderen Worten: die Collation der Index-Column könnte mit Hilfe eines ALTER TABLE-Statements nachträglich geändert werden und der Index würde diese Einstellung nach einem DROP/Re-Create erben. Dies könnte auch mit Hilfe von dacSQLStatement aus der Anwendung heraus funktionieren. Vielleicht hilft Ihnen das weiter?
Die Lösung ist nicht ganz das was ich suche (s. unten), könnte aber für anderen nützlich sein.
Ich habe wie folgt geantwortet:
Das ist schon eine interessante Variante, und könnte in Prinzip hilfreich sein, Danke.
Allerdings werde ich wahrscheinlich doch beim Backup/Restore bleiben, da ich konsequent überall bei der gleichen Collation bleiben will.
Ist mir schon lieber auf (SQL) Datenbankebene und nicht pro Index, sonst besteht die Gefahr, dass ich dies irgendwann für eine neue Tabelle/Index vergesse.
Vielleicht könnten Sie in einer zukünftigen Version erlauben, dass die Parameter für dbcreate als weiteres Attribut vom Element <connection> in der Upsize-Datei angegeben werden könnten?
Alaska Support hat dann meine Anmerkung bezüglich des zusätzlichen Upsizing-Attributes an die Entwicklung weitergeleitet.
Leider unterstützt die PGDBE die Angabe einer Collation aktuell noch nicht. Die Möglichkeit, die gewünschte Collation pro Index vorgeben zu können, steht aber bereits auf unserem Plan!
Als Work-Around für das Backup-Thema lässt sich eventuell ein Postgres-Feature nutzen; SQL-Indexe "erben" nämlich die Collation von der zugeordneten Column. Per default ist das die Collation der Datenbank. Es könnte aber auch mit Hilfe eines ALTER TABLE ALTER COLUMN .. COLLATION ..-Statements eine andere sein. Mit anderen Worten: die Collation der Index-Column könnte mit Hilfe eines ALTER TABLE-Statements nachträglich geändert werden und der Index würde diese Einstellung nach einem DROP/Re-Create erben. Dies könnte auch mit Hilfe von dacSQLStatement aus der Anwendung heraus funktionieren. Vielleicht hilft Ihnen das weiter?
Die Lösung ist nicht ganz das was ich suche (s. unten), könnte aber für anderen nützlich sein.
Ich habe wie folgt geantwortet:
Das ist schon eine interessante Variante, und könnte in Prinzip hilfreich sein, Danke.
Allerdings werde ich wahrscheinlich doch beim Backup/Restore bleiben, da ich konsequent überall bei der gleichen Collation bleiben will.
Ist mir schon lieber auf (SQL) Datenbankebene und nicht pro Index, sonst besteht die Gefahr, dass ich dies irgendwann für eine neue Tabelle/Index vergesse.
Vielleicht könnten Sie in einer zukünftigen Version erlauben, dass die Parameter für dbcreate als weiteres Attribut vom Element <connection> in der Upsize-Datei angegeben werden könnten?
Alaska Support hat dann meine Anmerkung bezüglich des zusätzlichen Upsizing-Attributes an die Entwicklung weitergeleitet.
Viele Grüße,
David
David
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Nur zur Info:
Die benötigte Zeit für Backup/Restore (ein paar Minuten) ist sehr klein im Vergleich zum Upsizing/Datentransfer (ein paar Stunden).
Die Konvertierung läuft nun seit Wochen nächtlich vollautomisiert durch für die erste Testphase, ernsthafte Probebetrieb beginnt nächste Woche.
Hier eine kurze Zusammenfassung des Ablaufs, falls es jemandem als Beispiel von Nutzen sein soll:
Im Anwendungscode war auch viel Arbeit nötig, aber nun kann ich mich auf die strategische Vorteile von Postgres freuen!
Die benötigte Zeit für Backup/Restore (ein paar Minuten) ist sehr klein im Vergleich zum Upsizing/Datentransfer (ein paar Stunden).
Die Konvertierung läuft nun seit Wochen nächtlich vollautomisiert durch für die erste Testphase, ernsthafte Probebetrieb beginnt nächste Woche.
Hier eine kurze Zusammenfassung des Ablaufs, falls es jemandem als Beispiel von Nutzen sein soll:
- Robocopy DBF-Dateien zum lokalen Rechner (und mit Anwendung neu indexieren)
- Im eigenen Xbase++ Programm:
- Felder namens "USER" in "BENUTZER" konvertieren (SQL-Keyword vermeiden), neu indexieren
- Strukturkonvertierung (viele "lose" DBFs in eine Tabelle sammeln)
- DbfUpsize über dbfupsize.lib ausführen. Zu merken in der .upsize-Datei:
- Volltext-Spalten, selbst in verschiedenen Tabellen müssen verschiedene Namen haben (z.B. nicht alle fts_col). Ich füge nun immer den Tabellennamen hinzu.
- Bei der Reihenfolge der Tabellen aufpassen wo ein Tabellenname eine Verlängerung von einem anderen ist, z.B. AR darf nicht nach ARTIKEL kommen, sonst stürzt Upsize ab.
- SQL-Datei mit psql ausführen (CREATE INDEX und CREATE VIEW Befehle)
- SQL Dump mit pg_dump erzeugen
- SQL-Datei mit psql ausführen (DROP/ALTER/CREATE DATABASE um Backup zu löschen/machen und Collation für neue Datenbank zu bestimmen).
Um Probleme mit Tasks, die darauf zugreifen, zu vermeiden (z.B. pgAdmin4 ist im Hintergrund hartnäckig), vor DROP bzw. ALTER "killen" mit:
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity
WHERE pg_stat_activity.datname = '<Datenbankname>' AND pid <> pg_backend_pid();
- SQL Dump mit pg_restore einspielen
- SQL-Datei mit psql ausführen (GRANT Befehle)
Im Anwendungscode war auch viel Arbeit nötig, aber nun kann ich mich auf die strategische Vorteile von Postgres freuen!
Viele Grüße,
David
David
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9394
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 104 Mal
- Danksagung erhalten: 364 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Ganz wichtig. Feldnamen wie "AT", "DO", "WHERE" oder "FROM" sind extrem problematisch! Aber es gibt eine Ersetzungsoption in der Upsize-Datei, die das vereinfacht.SQL-Keyword vermeiden
Herzlich,
Tom
Tom
- dtmackenzie
- Rekursionen-Architekt
- Beiträge: 265
- Registriert: Do, 22. Nov 2007 9:02
- Wohnort: Leipzig
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 22 Mal
- Kontaktdaten:
Re: Kann man die DB-Collation beim Upsize angeben?
Danke Tom!
Hmmm... Die Ersetzungsoption in der Upsize-Datei habe ich nicht benutzt, ich weiß nicht mehr genau warum (oder ob ich es damals übersehen habe).
Vielleich war das Problem, dass das Feld USER auch in der CDX-Datei vorkam? Ich indexiere neu nach der Ersetzung.
Also habe ich folgenden Code benutzt um die Ersetzung für alle DBFs im aktuellen Verzeichnis zu machen, könnte für andere Keywords erweitert werden, ist vielleicht aber überflüssig (und die Funktionen GetRec/Putrec auf alle Fälle, die machen eigentlich nur SCATTER/GATHER).
Hmmm... Die Ersetzungsoption in der Upsize-Datei habe ich nicht benutzt, ich weiß nicht mehr genau warum (oder ob ich es damals übersehen habe).
Vielleich war das Problem, dass das Feld USER auch in der CDX-Datei vorkam? Ich indexiere neu nach der Ersetzung.
Also habe ich folgenden Code benutzt um die Ersetzung für alle DBFs im aktuellen Verzeichnis zu machen, könnte für andere Keywords erweitert werden, ist vielleicht aber überflüssig (und die Funktionen GetRec/Putrec auf alle Fälle, die machen eigentlich nur SCATTER/GATHER).
Code: Alles auswählen
PROC U2B_Dir()
LOCAL aDbfFiles:=Directory("*.DBF"), nFiles:=LEN(aDbfFiles), i, cFilename
FOR i := 1 TO nFiles
cFilename := aDbfFiles[i, 1] // F_NAME == 1
cFilename := LEFT(cFilename, LEN(cFilename) - 4) // remove ".DBF"
U2B_DBF(cFilename)
NEXT
RETURN
********************************************************************************
PROC U2B_DBF(cFilename)
LOCAL aStructure, i, nFields, lHasUser:=.f., aRec:={}, cFileNameDBF:=cFileName+".dbf"
? cFilename
USE (cFileNameDBF) ALIAS Old NEW
PACK
aStructure := DbStruct() // read file structure
nFields := LEN(aStructure)
FOR i := 1 TO nFields
IF UPPER(aStructure[i,1]) == "USER"
aStructure[i,1] := "BENUTZER"
lHasUser := .t.
EXIT
ENDIF
NEXT
IF lHasUser
DbCreate("TEMP", aStructure ) // create and open
// temporary file with
USE Temp NEW // new structure
DBGOTOP()
SELECT Old
DBGOTOP()
// "APPEND FROM (cFileName)" doesn't work because it copies by field name...
DO WHILE !EOF()
GetRec(aRec)
Temp->(DBAPPEND(1))
Temp->(PutRec(aRec))
DBSKIP()
ENDDO
CLOSE Temp
CLOSE Old
ERASE (cFileNameDBF) // delete source file
RENAME Temp.dbf TO (cFileNameDBF) // rename temporary file
IF File( "TEMP.FPT" ) // when memo file exists
ERASE (cFileName + ".fpt") // delete old file
RENAME Temp.fpt TO (cFileName + ".fpt") // rename temporary file
ENDIF
ELSE
CLOSE Old
ENDIF
RETURN
****************************************************************
// Akt. Datensatz in Array speichern (für Kopierfunktionen)
****************************************************************
FUNC GetRec(aRec)
LOCAL i:=0, n:=FCOUNT()
ASIZE(aRec, 0)
FOR i := 1 TO n
AADD(aRec, FIELDGET(i))
NEXT
RETURN aRec
****************************************************************
// Array in akt. Datensatz speichern (für Kopierfunktionen)
****************************************************************
FUNC PutRec(aRec)
LOCAL i:=0, n:=FCOUNT()
FOR i := 1 TO n
FIELDPUT(i, aRec[i])
NEXT
RETURN aRec
Viele Grüße,
David
David