[SQLAlchemy/PostgreSQL] 'None' Strings

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
MoonKid
User
Beiträge: 106
Registriert: Mittwoch 10. Dezember 2014, 16:24

Bin mir nicht ganz klar, wie ich mit sowas umgehen soll.
Kurz formuliert: Wie gehe ich mit "leeren" Strings (länge also 0) in einer PostgreSQL-Datenbank um, wenn ich auf diese per SQLAlchemy zugreifen möchte? In Python wird das ja nicht zu einem String der Länge 0, sondern zu 'None', was wiederum kein String ist.

In Python ist das Feld (bzw. Spalte) so deklariert.

Code: Alles auswählen

__note = sa.Column('note', sa.String)
Würde auch gerne das SQL dazu zeigen, aber weiß nicht wie ich mir sowas in 'psql' anzeigen lassen kann. Die Verbindung zur Datenbank und ein '\d' bekomme ich schon hin. ;) Laut pgAdmin3 sieht der relevante SQL-Ausschintt so aus

Code: Alles auswählen

note text
.

Nun kann das Feld auch 'Null' sein, was in Python zu einem 'None' führt.
Das wiederum führt natürlich zu Fehlern, wenn ich sowas in ein GUI-Element (z.B. Textfeld) einfügen möchte, wo dort ein String erwartet wird.

Gibt es die Möglichkeit einen Leerenstring (Länge 0) als default-Wert zu definieren? pgAdmin hat das nicht zugelassen.

Die Klassenbeschreibung zu String ist in der sqlalchemy-doc wenig hilfreich. Daher weiß ich nicht, wie ich damit am elegantesten umgehen soll.
[url]file:///usr/share/doc/python-sqlalchemy-doc/html/core/types.html#generic-types[/url]

Die Länge kann ich nicht prüfen, weil 'None' kein String ist. Ein '__note == None' weißt er mit 'invalid syntax' zurück.
MoonKid
User
Beiträge: 106
Registriert: Mittwoch 10. Dezember 2014, 16:24

MoonKid hat geschrieben:'__note == None' weißt er mit 'invalid syntax' zurück.
Klar, da fehtle das ':' hinter dem if-statement. *duck*

Aber die Frage nach dem default-string der Länge 0 ist dennoch interessant.
BlackJack

@MoonKid: Die beiden Unterstriche bei `__note` gehören da nicht hin. :roll:

Mit leeren Zeichenketten geht man ganz normal um. Die werden auch als leere Zeichenketten geliefert. Wenn Du `None` bekommst, dann war das keine leere Zeichenkette sondern NULL in der Datenbank. Darauf musst Du halt prüfen wenn dieser Wert in der Datenbank vorkommen kann. Oder Du darfst NULL-Werte nicht in die Datenbank schreiben. Dann könnte man das auch direkt der Datenbank schon verbieten. Und natürlich kann man auch eine leere Zeichenkette als Default-Wert setzen. Wenn ``pgAdmin3`` das nicht hinbekommt, dann ist das ein Problem von dem Programm, nicht von der Datenbank.
MoonKid
User
Beiträge: 106
Registriert: Mittwoch 10. Dezember 2014, 16:24

BlackJack hat geschrieben:@MoonKid: Die beiden Unterstriche bei `__note` gehören da nicht hin. :roll:
Ja, das habe ich schon gehört. Aber das einfach so zu sagen, hilft Newbies nicht wirklich. Das müsste man schon begründen bzw. einen entsprechenden Link anbieten.

Mir ist bewusst das ein Doppelunterstrich nur per Konvention privat bedeutet, das Attribut aber weiterhin unter (abgewandelten) Namen direkt ansprechbar ist. Der Fachbegriff dazu fällt mir grad nicht ein.

Fakt ist aber, dass nach meinem OO-Design das Attribut privat ist. Das muss ich auch irgendwie abbilden. Und ein Unterstrich ist nun mal protected und nicht privat.

Bisher habe ich noch keine Verfahrensempfehlungen zu diesem Aspekt gelesen.
Die Frage wäre auch, wass sich den die Python-Entwickler mit den Unterstrichen eigentlich gedacht haben?
BlackJack hat geschrieben:Mit leeren Zeichenketten geht man ganz normal um. Die werden auch als leere Zeichenketten geliefert. Wenn Du `None` bekommst, dann war das keine leere Zeichenkette sondern NULL in der Datenbank.
Da hatte ich mich evtl. schlecht ausgedrückt. Die Felder sind NULL, das ist mir klar, dass ich deswegen 'None' zurückbekomme.
BlackJack hat geschrieben:darfst NULL-Werte nicht in die Datenbank schreiben. Dann könnte man das auch direkt der Datenbank schon verbieten. Und natürlich kann man auch eine leere Zeichenkette als Default-Wert setzen.
Das ist die Quizfrage: Wie (per SQL)? Ist ja nicht so, dass ich es schon versucht hätte.
BlackJack

@MoonKid: Vergiss bitte Begriffe wie ``private`` und ``protected``. Die machen keinen Sinn in einer Sprache wo alle Attribute `public` sind. Per Konvention bedeutet *ein* führender Unterstrich „Implementierungsdetail, Finger weg”. Also wenn Du unbedingt möchtest kannst Du das für Dich privat ``private`` nennen.

Das offizielle Tutorial dazu: https://docs.python.org/2/tutorial/clas ... references

Wie man Default-Werte in SQL angibt kann man üblicherweise in der Dokumentation der Datenbank finden die man verwendet: http://www.postgresql.org/docs/current/ ... table.html

Also zum Beispiel:

Code: Alles auswählen

CREATE TABLE test (column_name TEXT DEFAULT '');
Wenn man zusätzlich ``NULL`` als Wert verbieten möchte kann man noch ein ``NOT NULL`` einfügen.
Benutzeravatar
pillmuncher
User
Beiträge: 1527
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

MoonKid hat geschrieben:Mir ist bewusst das ein Doppelunterstrich nur per Konvention privat bedeutet, ...
Und ein Unterstrich ist nun mal protected und nicht privat.
Beides ist falsch.

Ein führender Unterstrich bedeutet (per Konvention): dieses Attribut it ein Implementierungsdetail, das nicht zum offiziellen Interface gehört. Wer weiß, was er tut, kann das Attribut gerne verwenden, trägt dann aber auch das Risiko, wenn etwas schief geht.

Mindestens zwei führende Unterstriche (bei höchstens einem abschließenden Unterstrich) führen dazu, dass Python auf den Attributnamen private name mangling anwendet. Das braucht man selten, und man verwendet es lediglich dazu, um Namenskonflikte bei Mehrfachvererbung aufzulösen.

Es wurde hier im Forum schon oft geschrieben: man kann nicht einfach die Konzepte einer Programmiersprache auf eine andere anwenden. Jede Programmiersprache kodiert auch einen Blick darauf, welche Probleme wichtig sind und welche nicht, und wie bestimmte Probleme gelöst werden sollen, und wie nicht. Explizite Privatheit wurde von Guido als nicht so wichtig erachtet. Deswegen gibt es sie nicht als explizites Sprachkonstrukt.

Und falls man wirklich Konzepte einer anderen Sprache auf Python übertragen möchte, dann sollte man solche aus Lisp nehmen, nicht aus C++/C#/Java, denn Python ist viel enger mit ersterem verwandt, als mit letzteren.
In specifications, Murphy's Law supersedes Ohm's.
Antworten