Sphinx: Unexpected unindent

Sphinx ist das Standardtool zur Dokumentation von Python Code. Sphinx liest direkt DocStrings aus dem Quellcode aus und bereitet dabei eine Dokumentation auf.

Ideal wäre es wenn das natürlich ganz ohne Änderungen am Code oder der Dokumentation abläuft und man nicht noch mehr syntatktische Regeln beachten muss.

WARNING: Block quote ends without a blank line; unexpected unindent.

Diese Fehlermeldung sagt allerdings etwas anderes. Dies ist ein Warning das Sphinx beim Kommando „make html“ ausgespuckt hat.

Ursache dafür war dieser Docstring mit Einrückungen:


def dummyfunction():

'''Das ist ein langer Kommentar mit mehreren Punkten:

   - Punkt1 : Lorem ipsum
     dolor il

   - Punkt2: ....

'''

....

Veröffentlicht unter Allgemein | Hinterlasse einen Kommentar

S/MIME: Export des öffentlichen Schlüssels (P12->CER)

Im Artikel S/MIME in Outlook einrichten beschreibe ich, wie man z.B. vom Anbieter Comodo ein persönliches Zertifikat für die Verschlüsselung bekommt.

Dabei erhält man eine P12-Datei, die auch den privaten Schlüssel enthält. Diese Datei darf nicht in fremde Hände gelangen.

Möchte man nun den öffentlichen Schlüssel extrahieren gibt es hier eine Anleitung dazu wie dies ohne Kommandozeilen Tools (Openssl) möglich ist.

Dieser Export ist z.B. für die verschlüsselte Kommunikation via Datev notwendig. Im Portal https://demvreply.datevnet.de/ gibt es dazu die Möglichkeit einen öffentlichen Schlüssel hochzuladen.

Veröffentlicht unter Allgemein | Hinterlasse einen Kommentar

SQLAlchemy: Joined Table Inheritance

Eigentlich lässt die Dokumentation des ORM SQLAlchemy für Python keine Wünsche offen. Auch das Klassenmapping mit Polymorphy ist gut dokumentiert. Was aber noch etwas zu kurz kommt ist die Datenbanksicht.

Ich möchte hier das Beispiel der Dokumentation aufgreifen.
Von einer Basisklasse „Employee“ werden zwei weitere Klassen „Manager“ und „Engineer“ abgeleitet.

Grundsätzlich gibt es verschiedene Strategien Klassenhirarchien abzubilden

  • Joined Table Inheritance:
    Bei dieser Variante gibt es für jede Klasse eine eigene Tabelle. Die beiden Subklassen erhalten eigene Tabellen mit Referenzen auf die Basisklasse.
  • Single Table Inheritance:
    In dieser Form wird die ganze Klassenhierarchie in einer einzelnen Tabelle abgebildet. Aus Blick des Python Codes ist alles sauber. In der Datenbank gibt es aber in der Tabelle Felder, die nur abhängig vom Typ befüllt werden dürfen. Echte Datenbank-Constraints sind damit fast unmöglich.
  • Concrete Table Inheritance:
    Hier gibt es auch wieder für jede Klasse eine Tabelle. Diesesmal haben die Subklassen aber keine Foreign Key Beziehung mit der Basisklasse. Jede Tabelle dupliziert auch die Spalten der Basisklasse. Aus Sicht der Datenbank gibt es nun keine Zentrale Tabelle mehr in der alle „Employees“ erfasst sind. Es lässt sich damit auch kein Foreign Key Constraint mehr setzen.

Um ein sauberes Datenbankmodell zu erhalten, ist somit nur die „Joined Table Inheritance“ zu empfehlen:

  • Auf Spaltenebene können ohne Problem Check-Constraints und Not-Null-Constraints definiert werden.
  • Auch ohne die Kenntnis des SQLALchemy Mappings ergibt sich für andere Anwendungen ganz automatisch welche Felder für welche Klasse gefüllt werden können.
  • Die Basisklasse kann durch andere Tabellen via Foreign Key Constraint referenziert werden.

Wie wird nun eine Joined Table Inheritance in Python gemappt?

class Employee(Base):
    __tablename__ = 'employee'
    Id = Column(Integer
                , primary_key=True)
    Name = Column(String(50))

class Manager(Employee):
    __tablename__ = 'manager'
    Id = Column(Integer
                , ForeignKey(Employee.Id)
                , primary_key=True)
    ManagerStatus = Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity': 'manager',
    }

class Engineer(Employee):
    __tablename__ = 'engineer'
    Id = Column(Integer
                , ForeignKey(Employee.Id)
                , primary_key=True)

    EngineerDegree= Column(String(50))

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
    }

Daraus lassen sich diese Create-Statements generieren.

create_engine('sqlite:///', echo= True)
Base.metadata.create_all(bind=engine)

CREATE TABLE employee (
	"Id" INTEGER NOT NULL, 
	"Name" VARCHAR(50), --Felder der Basisklasse sind hier  ...
	PRIMARY KEY ("Id")
);
-- und werden in den abgeleiteten Tabelle nicht mehr wiederholt
CREATE TABLE engineer (
	"Id" INTEGER NOT NULL, 
	"EngineerDegree" VARCHAR(50), 
	PRIMARY KEY (id), 
	FOREIGN KEY(id) REFERENCES employee ("Id")
);

CREATE TABLE manager (
	"Id" INTEGER NOT NULL, 
	"ManagerStatus" VARCHAR(50), 
	PRIMARY KEY (id), 
	FOREIGN KEY(id) REFERENCES employee ("Id")
);

Wichtig ist dabei der Fremdschlüssel in den abgeleiteten Klassen, der auf die Basisklasse zeigt:

#Employee.Id bezieht sich dabei auf den Klassen/Attributnamen,
#nicht etwa auf Tabellen oder Spaltenbezeichnungen
Id = Column(Integer,ForeignKey(Employee.Id), primary_key=True)

Vergisst man diesen Fremdschlüssel erhält man folgende Meldung:

  Can’t find any foreign key relationships between ‚employee‘ and ‚manager‘.

 

Veröffentlicht unter Programmierung, Python | Verschlagwortet mit , , , , | Hinterlasse einen Kommentar

Datenschutz für kleine Unternehmen – Handreichung

Das Thema Datenschutz betrifft jedes Unternehmen, egal ob groß oder klein. Aber gerade in kleineren Unternehmen scheint das Thema unüberwindbar und wird gar nicht erst angegangen.

Das Bayrische Landesamt für Datenschutzaufsicht hat auf ihrer Website eine Todo-Liste speziell für einzelne Branchen online gestellt.

https://www.lda.bayern.de/de/kleine-unternehmen.html

 

 

Veröffentlicht unter Security | Hinterlasse einen Kommentar

GIT-Cheatsheet

Wer bereits mit den Grundsätzen der Versionsverwaltung in SVN vertraut ist, wird sich auch in GIT schnell zurecht finden. Einer der Hauptunterschiede ist, dass nun jeder zur Working-Copy auch noch das komplette Repository lokal hält.

Änderungen am Code werden also erst an das lokale Repository und dann an ein entferntes verteilt. Deswegen sind auch die Begrifflichkeiten für SVN-Umsteiger erst verwirrend.

Wichtige GIT-Begriffe im Schnellcheck:

Weiterlesen

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , | Hinterlasse einen Kommentar

Regular Expressions und Top Level Domains

Eine häufige Aufgabe in der Programmierung ist das suchen/validieren von Email-Adressen. Mal davon abgesehen, dass ein regulärer Ausdruck nur bedingt dazu benutzt werden kann, funktionieren filtern grobe Näherungen schon mal die meisten.  Weiterlesen

Veröffentlicht unter Programmierung | Verschlagwortet mit , , , , , | Hinterlasse einen Kommentar

Oracle SQLCL Export in UTF8 mit BOM

Der Export von Daten mit SQLCL funktioniert ähnlich wie beim Großvater SQLPlus.

Leider bietet SQLCL keine Option mit welcher Kodierung die Ausgabe erfolgt. Das lässt sich mit JAVA_TOOL_OPTIONS einstellen. Weiterlesen

Veröffentlicht unter Oracle | Verschlagwortet mit , , , , , , , | Kommentare deaktiviert für Oracle SQLCL Export in UTF8 mit BOM

Oracle SQL String Split in mehrere Zeilen/Rows

Auch mit dem besten Datenbankmodell gibt es Importe und Situationen in denen in einem Feld mehrer Werte durch Separatoren getrennt hinterlegt sind.

Um diese Werte in Zeilen umzuwandeln gibt es genügend Varianten im Internet zu finden: z.b. auf Stackoverflow. Die meisten Lösungen arbeiten dabei mit regulären Ausdrücken und der Funktion „regexp_substr“. Die gehen einfach von der Hand, wirken sich bei größeren Datenmengen, wie sie in einem Datawarehouse vorkommen, aber durchaus auf die Performance aus. Um nicht mit Kanonen auf Spatzen zu schießen, läßt sich das Splitten alternativ mit einfachen Stringfunktionen lösen. Weiterlesen

Veröffentlicht unter Oracle | Verschlagwortet mit , , , , | Kommentare deaktiviert für Oracle SQL String Split in mehrere Zeilen/Rows

Azure Datawarehouse: SQL Server Management Studio Verbindung

Als erster Teil einer kleinen Serie zum Thema Azure Warehouse beschäftigte ich mich heute mit der Verbindung des SQL Server Management Studios (kurz SSMS) zum Azure Datawarehouse. Weiterlesen

Veröffentlicht unter SQL | Kommentare deaktiviert für Azure Datawarehouse: SQL Server Management Studio Verbindung

ORA-12899: Aber mein String ist doch nicht zu lang?

Mit dem Fehler ORA-12899 möchte die Datenbank sagen, dass eine Zeichenfolge nicht in die gewünschte Varchar2 Spalte passt. In der Regel ist der String auch wirklich viel zu lang für die Spalte und der Fehler liegt woanders.

In vielen anderen Fällen ist vielleicht eine Eigenheit des Varchar2 Datentyps unter Oracle die Ursache. Weiterlesen

Veröffentlicht unter Oracle | Kommentare deaktiviert für ORA-12899: Aber mein String ist doch nicht zu lang?