Kann man die DB-Collation beim Upsize angeben?

Hier dreht es sich um den PostGre Server

Moderator: Moderatoren

Antworten
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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?
Viele Grüße,
David
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

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
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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!
Viele Grüße,
David
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

...anstatt eine neue anzulegen...
Viele Grüße,
David
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

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
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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.
Viele Grüße,
David
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

Oh, da interessiert mich die Antwort auch! :)
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

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.
Herzlich,
Tom
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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.
Viele Grüße,
David
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

...und mit englischen Meldungen kann ich auch gut leben. :wink:
Viele Grüße,
David
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

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
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

..und mit englischen Meldungen kann ich auch gut leben.
Wir übersetzen im Logger. Manch ein Kunde oder Kunden-ITler macht das selbst.
Herzlich,
Tom
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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.
Viele Grüße,
David
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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:
  • 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)
Ich hoffe, dass diese Zusammenfassung anderen die Konvertierung erleichtert, oder wenigstens hilft, ein paar Fallstricken zu vermeiden.
Im Anwendungscode war auch viel Arbeit nötig, aber nun kann ich mich auf die strategische Vorteile von Postgres freuen! :D
Viele Grüße,
David
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9345
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 100 Mal
Danksagung erhalten: 359 Mal
Kontaktdaten:

Re: Kann man die DB-Collation beim Upsize angeben?

Beitrag von Tom »

SQL-Keyword vermeiden
Ganz wichtig. Feldnamen wie "AT", "DO", "WHERE" oder "FROM" sind extrem problematisch! Aber es gibt eine Ersetzungsoption in der Upsize-Datei, die das vereinfacht.
Herzlich,
Tom
Benutzeravatar
dtmackenzie
Rekursionen-Architekt
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?

Beitrag von dtmackenzie »

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).

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
Antworten