Article
0 comment

Separating structure and semantics

There is a great and simple rule, known as “Micha’s Golden Rule”, which goes back to Micha Gorelick (@mynameisfiber). It states:

Do not store data in the keys of a JSON blob.

This means, that instead of writing a JSON dataset holding people and their gaming scores like this:

{
  "Volker": 100,
  "John": 300
}

you should use something like:

[
  {
    "name": "Volker",
    "score": 100
  },
  {
    "name": "John",
    "score": 300
  }
]

First of all, it is good practice, to separate data and its meaning. Second it simplifies software development. And here is why:

One reason is, that in the first form you have no idea, what exactly the number associated with the name means. And when accessing the data you need to know the keys. But the keys are part of the data. So you first have to parse the whole file, separate the keys and iterate over them. In the second case you can iterate over a set of completely identical structured data sets and fetch names and scores.

This rule not only holds true for JSON but for any structured data like XML or yaml. Consider the following modified XML example from the SimpleXML section of the PHP manual:



 
  PHP: Behind the Parser
  Rasmus Lerdorf
  1
 

In PHP you would access the director in this way:

movie[0]->director;
?>

Now if you would like to use the directors name as a key to get the number of oscars he won, it would look like:



 
  PHP: Behind the Parser
  1
 

This is perfectly valid but stupid XML. And to access the data you need to know the name of the director:

movie[0]->RasmusLerdorf;
?>

Doesn’t make too much sense, hm? One additional drawback I didn’t mention but that you nevertheless saw: the keys of a data structure language often are subject to several limitaions. In XML element names e.g. there can’t be spaces. So you have to work around that e.g. by camelcasing the name. To get the name back in readable form, you would have to parse it and insert spaces at the correct positions. Which can be impossible with human names, since there are camelcased names like “DeLorean”.

Considering this rule is not always obvious but can save you a lot of nerves. Take care!

Article
0 comment

I wish I could look at that in my browser …

Sometimes you would like to see some information, which is readily available from a unix command in your browser. If it’s in a private network and / or the information doesn’t do any harm when read by unauthorized people or it’s for a rather short period of time, then ashttp does the trick.
ashttp is a python script by Julien Palard (@sizeof) using a headlesss vt100 terminal emulator to run a script each time the http server gets a request, grab the output and deliver it via http to the requesting browser.
For example the output of top:

ashttp -p 8081 top

This will start up an http server on port 8081 (you can also use –port) and every request to that server will deliver the output of a fresh top command:
ashttp_top
At the moment there seems to be a small problem with forwarding the command line parameters of the unix command, so you can circumvent that by putting your more complex statement into a shebang’ed shell script and calling this one from ashttp:

#!/bin/bash
watch -n1 ls -lah /tmp

Have fun!

Update: @n770 correctly mentioned, that having swig installed is a prerequisite to building the python hl_vt100 module.

Article
0 comment

PostgreSQL: Backup a large database to disk

I really like database dumps with complete column inserts. You can read them, browse, search for some special data and even manipulate them. The most simple way to create such a readable backup is:

pg_dump --column-inserts --inserts --if-exists --clean --create -f FILENAME.sql DATABASENAME

There is one drawback: the files are large compared to the actual information stored und im- and export are rather slow. But there is a backup format that is both compressed and fast. It’s called “directory format”:

pg_dump -Fd -f DIRECTORYNAME -d DATABASENAME

This creates a directory called DIRECTORYNAME and dumps the content of DATABASENAME in a compressed format.
Getting the data back into the database is done with pg_restore:

pg_restore -C -d DATABASENAME DIRECTORYNAME

The -C option creates the database prior import.

Article
1 comment

PostgreSQL: Copy a table structure and data

Once again a short notice about some nifty PostgreSQL feature you might not be aware of. It’s quire simple to copy the structure of a table with:

CREATE TABLE table2 ( like table1 INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES );

Now you can copy data with or without some sort of filter:

INSERT INTO table2 SELECT * FROM table LIMIT 100;

Hope that helps.

Article
0 comment

PostgreSQL: Convert an hstore column to jsonb

I’m involved in a tech scouting project, where I designed a PostgreSQL database schema using an hstore column to store additional a priori unspecified data to every record in that table. For some historical reason I decided to use an hstore column instead of one of the much more versatile JSON column types.

Historical priorities change and so they did in that project. Now I wanted to use that column as JSONB. As always in SQL columns are changed with an ALTER TABLE … ALTER COLUMN statement. In this case the conversion of the content is a bit more complex, but giving PostgreSQL some hint about what we expect does the job.

First let’s create a table to play with and insert one row of data:

CREATE TABLE hstore_data (data hstore);
INSERT INTO hstore_data (data) VALUES ('key1 => "value1", key2 => "value2"');

Let’s see, if it looks OK:

SELECT * FROM hstore_data;

Yields:

                data                
------------------------------------
 "key1"=>"value1", "key2"=>"value2"
(1 row)

Fine. Next step is the magic column conversion:

ALTER TABLE hstore_data ALTER COLUMN data TYPE JSONB USING CAST(data as JSONB);

Another look:

SELECT * FROM hstore_data;

And we get:

                 data                 
--------------------------------------
 {"key1": "value1", "key2": "value2"}
(1 row)

Mission accomplished.

Article
0 comment

Why “all incl” work contracts are a bad idea

It’s a constantly spreading habit of employers (at least in Germany) to offer work contracts which contain a passage saying that all overtime hours are included in the base salary. While this sounds like a good idea for employers, it eventually is not.

First there is some moral type of issue. The amount of work needed to fulfill a customer project is a entrepreneurial risk. This is why some people are employed and some are freelancing. The employed ones are offered a (somehow) fixed salary for his work time. The entrepreneur gets the surplus for taking the risk. Not paying overtime hours means to shift this entrepreneurial risk to the employee. Thats bad.

Then there is motivational issue. If I’m not paid for my time I have no interest whatsoever in a personal commitment exceeding my stipulated work time. My first project agency partner once said: “Think well, when investing your time without gain. Your work time is your only commodity. Don’t waste it without revenue.”

So think well when offering a contract to a prospective coworker: if you are interested in hiring a guy who cares for the project, then pay her/him by the hour. Don’t expect to be presented with his/her time.

(Image by http://deathtothestockphoto.com, License)

Article
2 comments

Klein und gut

Neulich rauschte ein Blogposting des kleinen Seitenstraßenverlages an mir vorbei. Darin geht es darum, daß so mancher Verlag mit den so oft romantisierten kleinen unabhängigen Buchhändlern seine Probleme hat. Und daß man bei Amazon wenigstens gleich fair (bzw. unfair) zu allen Großverlagen behandelt wird. Für keine der beiden Parteien wird eine Lanze gebrochen, beide haben ihre Vor- und Nachteile. Fand ich spannend.

Das machte mich aber auch auf ein typisches Marketing- bzw. Vertriebsproblem der kleinen Verlage aufmerksam: wenn die Buchhändler sie nicht promoten, wo findet man sie dann? Ja klar, im Internet. Marketing über die sozialen Netzwerke etc. Aber da kämpft jeder Verlag für sich alleine. Damit bleibt die Sichtbarkeit im Promillebereich. Andere Branchen haben da eine interessante Lösung. Amazon Shops, eBay und Dawanda eint ein Prinzip: hier finden sich tausende kleinere Anbieter unter einem Dach. Ich brauche keine Google-Suche, um eine bestimmte Angebotsseite zu finden. Auch wenn auf solchen Portalen “die Konkurrenz” ja mit vertreten ist, steigt die eigene Sichtbarkeit für potentielle Kunden an. Diese Portale haben natürlich auch ihre Probleme für Anbieter: die Gebühren für Einstellen und Verkauf sind teilweise exorbitant (gut, Verlage sind da ganz andere Abschläge aus der Buchhandelsbranche gewohnt) und die Plattform gehört einem Unternehmen. Das macht die Anbieter abhängig. Wenn z.B. eBay keinen Bock mehr auf professionelle Anbieter hat, sperren sie diese aus und die Anbieter sind mit einem Schlag nicht nur von ihrer potentiellen, sondern auch von der Stammkundschaft getrennt.

Auf Twitter entstand dazu folgende kurze Diskussion:

Meine Idee dazu wäre:

  • Was wäre, wenn es ein solches Portal für Kleinverlage gäbe?
  • Inhaber bzw. Betreiber sollte dabei eine Art Dachorganisation der Verlage sein, damit keine für die Verlage unfaire Gewichtsverteilung auftritt.
  • Zudem braucht es einen technischen Betreiber, der das Ganze entwickelt und für den Betrieb sorgt.
  • Über die Höhe evtl. anfallender Gebühren müßte man sich als technischer Betreiber mit dem inhaltlichen Betreiber einigen.
  • “Die Kleinverlage” ist eine sehr heterogene Gruppe. Man muß Mittel und Wege finden, den Verlagen das Einstellen der Bücher zu vereinfachen.

Klingt ja alles ganz nett, nicht wahr? Warum hat es bisher noch niemand gemacht? Vielleicht war das Kosten-Nutzen-Verhältnis nicht gut genug, vielleicht hatte jemand keine gute Verbindung zu Literatur an sich und den kleinen Verlegern (eine direkte Verbindung hab ich ja auch nicht). Wer weiß?
Nächste Frage: warum leg ich mich so ins Zeug für eine Idee, die dann offensichtlich anderen zu Gute kommt? Das ist gar nicht so einfach zu beantworten. Weil ich Literatur mag. Weil ich kleine Verlage mag. Weil ich die großen meist nicht mag. Weil der viel beschworene Zusammenbruch des Papierbuchmarktes vor allem die Großverlage mit ihren unglaublich aufwendigen Mechanismen treffen wird und die Kleinverlage vielleicht eine Möglichkeit sind, dieses Medium Buch, an dem ich so hänge, zu erhalten. Schaun wir mal, was jetzt passiert …

Nachtrag: eines ist schon passiert: der Seitenstraßenverlag hat die Reaktionen auf sein Posting mal zusammen gefaßt und im letzten Absatz werde auch ich mit meiner Idee kurz nicht-namentlich erwähnt ;)

Article
0 comment

Starting with Grails and Neo4J

Since Stefan Armbruster is a bit short of time to update the documentation of the Neo4J plugin for Grails I thought I start a short series of postings describing my progress in using Neo4J as a graph database for a Grails based application. I will use the REST API of Neo4J and not the embedded version.
Like always it starts with additions to grails-app/conf/BuildConfig.groovy. First we need to add the Neo4J maven repository to the repositories section:
[pyg l=”groovy”]repositories {
// …
mavenRepo ‘http://m2.neo4j.org/content/repositories/releases/’
} [/pyg]
Then I set my versions:

[pyg]neo4jVersion=”2.0.3″
neo4jRestVersion=”1.9″[/pyg]

 
Now we need to declare the dependencies:
[pyg]dependencies {
//…
compile “org.neo4j:neo4j-community:$neo4jVersion”
compile group:”org.neo4j”, name:”neo4j-graphviz”, version: neo4jVersion
runtime group:”org.neo4j”, name:”neo4j-shell”, version: neo4jVersion
runtime “org.neo4j:neo4j-rest-graphdb:$neo4jRestVersion”
}[/pyg]

En bloc that looks like this (caveat: this code block also installs the angularjs plugin!):

[pyg]grails.project.dependency.resolver = “maven” // or ivy
grails.project.dependency.resolution = {
// inherit Grails’ default dependencies
inherits(“global”) {
}
log “error”
checksums true
legacyResolve false

repositories {
    inherits true // Whether to inherit repository definitions from plugins

    grailsPlugins()
    grailsHome()
    mavenLocal()
    grailsCentral()
    mavenCentral()
    // uncomment these (or add new ones) to enable
    // remote dependency resolution from public Maven repositories
    //mavenRepo "http://repository.codehaus.org"
    //mavenRepo "http://download.java.net/maven/2/"
    //mavenRepo "http://repository.jboss.com/maven2/"
    mavenRepo 'http://m2.neo4j.org/content/repositories/releases/'
}

neo4jVersion="2.0.3"
neo4jRestVersion="1.9"

dependencies {
    // runtime 'mysql:mysql-connector-java:5.1.29'
    // runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
    test "org.grails:grails-datastore-test-support:1.0.2-grails-2.4"

    compile "org.neo4j:neo4j-community:$neo4jVersion"
    compile group:"org.neo4j", name:"neo4j-graphviz", version: neo4jVersion
    runtime group:"org.neo4j", name:"neo4j-shell", version: neo4jVersion
    runtime "org.neo4j:neo4j-rest-graphdb:$neo4jRestVersion"
}

plugins {
    // plugins for the build system only
    build ":tomcat:7.0.55"

    // plugins for the compile step
    compile ":scaffolding:2.1.2"
    compile ':cache:1.1.8'
    compile ":asset-pipeline:1.9.9"

    compile ":angularjs:1.0.0"

    // plugins needed at runtime but not for compilation
    runtime ":hibernate4:4.3.6.1" // or ":hibernate:3.6.10.18"
    runtime ":database-migration:1.4.0"
    runtime ":jquery:1.11.1"

}

}[/pyg]

This will get you started with the integration itself. In the next posting I will show, how to access data in the Neo4j database from a controller.

Article
0 comment

Neuer Wein in alten Schläuchen

Heute morgen las ich in der Frankfurter Sonntagszeitung vom letzten Wochenende (ja, ich komme nie dazu, eine Sonntagszeitung wirklich durchzulesen, das mach ich den Rest der Woche) ein Interview mit Thomas Vollmoeller, dem Vorstandsvorsitzenden von Xing. Darin wies er eindringlich darauf hin, wie sehr sich die Arbeitswelt geändert habe und noch ändere. Stellenbewerber hätten heute ganz andere Möglichkeiten als früher. Das erfordere auch von Firmen- oder Personalchefs ein anderes Daseinsmodell. Er zitierte hier den so oft strapazierten, aber ausnahmsweise mal angebrachten Begriff des Paradigmenwechsels.

Der Chef 2.0 soll Mitarbeitern morgens einen Grund zum Aufstehen und zur Arbeit gehen geben. Man müsse eine gemeinsame Aufgabe und Auffassung von dem, was man da tue entwickeln. Ihr seht schon, ich vermeide bewußt – so wie Vollmoeller – den Begriff ‘Vision’. Allerdings könne ein Mitarbeiter nur dort einem Firmenchef oder Vorgesetzter vertrauen, wo dies auf Gegenseitigkeit beruhe. An der Stelle schweiften meine Gedanken etwas ab, weil ich schon den Eindruck habe, daß sich da in den Chefetagen etwas bewegt hat. Ich bin bzw. war ja auch mal Chef und hatte eigene Mitarbeiter. Und habe ähnlich darüber gedacht wie er. Und ich habe aus vielen Firmen, in denen ich als Berater tätig war den Eindruck, daß das mit der Gegenseitigkeit noch nicht so recht funktioniert.

Ich kenne sehr viele Mitarbeiter, vorwiegend in IT Firmen, weil ich dort meist tätig war, die sich zwar über mangelndes Entgegenkommen ihres Chefs beschweren, aber selbst noch das “Wir gegen Die” Szenario im Kopf haben. Ich meine diese klassische Sicht von Gewerkschaften auf Firmen als das Böse schlechthin, daß dem Mitarbeiter die Lebenskraft aussaugt und dem man mit Blut und Schweiß einen Obulus abtrotzt. Ich weiß, daß ich hier maß- und hemmungslos übertreibe. Ich wollte das Bild möglichst bunt malen ;)

Natürlich kann man sich jetzt fragen, wie sehr die defensive Einstellung der Mitarbeiter auf Enttäuschungen mit dem Unternehmen beruhen. Und man sollte nicht aus dem Auge lassen, daß Firma und Mitarbeiter natürlich nicht alte Freunde sind, denen man blind vertrauen kann. Ich denke, ein Stück weit sind schon bestehende Arbeitsverträge das Problem. In neuen Verträgen kann man flexible Modelle aushandeln und dann eben auch deren Spielregeln festlegen. Alte klassische Arbeitsverträge als Grundlage flexibler Mitarbeiter zu sehen, die ein Stück weit für ihre Firma unternehmerisch denken, ist wohl etwas schwierig.

Und wenn man die neuen Arbeitsplatzregeln des Gesetzgebers liest, stellt man fest, daß die zwar dem Schutz der Mitarbeiter dienen sollen, aber eben auch exakt Null Flexibilität enthalten. Da sollen Arbeitszeiten immer und auf jeden Fall erfaßt werden. Das ist gut, weil es viele Menschen gibt, die ohne eine solche Kontrolle (wie effektiv die ist, sei mal dahin gestellt) von ihren Unternehmen oder sogar sich selbst, regelrecht ausgebeutet werden. Firmen wie Best Buy in den USA, die das “ROWE” (result oriented work environment) Prinzip eingeführt haben, sucht man trotz guter Debattenbeiträge wie den des geschätzten Autors Markus Albers leider in Deutschland meist immer noch vergeblich.

Ich kenne allerdings Unternehmen, die eine, man möchte sagen typisch deutsche, Mittelweglösung gefunden haben: dort gibt es eine Arbeitszeiterfassung. Aber da tragen die Mitarbeiter selbst ihre Zeiten ein. Ob die Werte richtig sind, kontrolliert im Normalfall niemand. Ich gehe mal davon aus, daß jemand, der täglich 8h einträgt, aber nie im Haus ist, schon auffallen würde. Die Zeiten, die da nachher in Summe heraus kommen pro Monat, interessieren weitestgehend auch niemanden. Problematisch wird das an der Stelle nur, wenn diese Stundenkontingente als Basis für die Abrechnung von Kundenprojekten benutzt werden. Das funktioniert an der Stelle nur, wenn der Kunde dem Unternehmen als Dienstleister ein gewisses Vertrauen entgegen bringt.

Article
0 comment

From JSON to CSV to SQL

The task

I recently had the problem, that I had to insert JSON data sets into a PostgreSQL database. As rows, not as JSON field type.

The JSON represents a network of nodes and links and looked like this:

{
  "links": [
    {
      "source": "22",
      "target": "17",
      "value": 1
    },
    {
      "source": "18",
      "target": "14",
      "value": 1
    },
...
  ],
  "nodes": [
    {
      "name": "Resource 32",
      "image": "/mydemo/images/icon1.svg",
      "group": 1,
      "image_width": 45,
      "image_height": 45
    },
    {
      "name": "Resource 17",
      "image": "/mydemo/images/icon2.svg",
      "group": 1,
      "image_width": 45,
      "image_height": 45
    },
...
  ]
}

What I needed:

  1. 1. split JSON into nodes and links separately
  2. 2. convert to CSV
  3. 3. add an ID field as first column and primary key
  4. 4. number data rows with ID from 1 to n
  5. 5. delete the ugly path “/mydemo/images/”, leaving only the filename
  6. 6. create table in PostgreSQL DB and insert data

Create CSV from JSON

For this I used the brilliant Python based cvskit package. This is done in 2 steps:

The first step completes tasks 1 to 5:

underbrace{tt in2csv -k nodes myfile.json}_{mbox{Term 1}}nolinebreak[4]midnolinebreak[4]underbrace{tt nl -v0 -s,}_{mbox{Term 2}}nolinebreak[4]midnolinebreak[4]underbrace{tt perl -pequad's/hat{quad}{backslash}s+//'}_{mbox{Term 3}}nolinebreak[4]midnolinebreak[4]underbrace{tt sedquad"s/hat{quad}0,/id,/g;s#/visdemo/images/##g"}_{mbox{Term 4}}nolinebreak[4]>nolinebreak[4]mbox{tt nodes.csv}

Term 1: Export subarray with key nodes.
Term 2: Number lines starting with zero (uses unix tool nl). Delimiter is colon.
Term 3: Strip leading spaces.
Term 4: Replace “0,” in first line with col name, strip image path.

The same for the links section of the JSON file:

underbrace{tt in2csv -k links graph3345.json}_{mbox{Term 1}}nolinebreak[4]midnolinebreak[4]underbrace{tt nl -v0 -s,}_{mbox{Term 2}}nolinebreak[4]midnolinebreak[4]underbrace{tt perl -pequad's/hat{quad}{backslash}s+//'}_{mbox{Term 3}}nolinebreak[4]midnolinebreak[4]underbrace{tt sedquad"s/hat{quad}0,/id,/g"}_{mbox{Term 4}}nolinebreak[4]>nolinebreak[4]mbox{tt links.csv}

Term 1: Export subarray with key links.
Term 2: Number lines starting with zero (uses unix tool nl). Delimiter is colon.
Term 3: Strip leading spaces.
Term 4: Replace “0,” in first line with col name.

Insert CSV into database

Now we need another tool from the csvkit tool chain, which reads CSV and builds an SQL CREATE TABLE statement and inserts the data into the created table.

csvsql --db postgresql://user:passwd@localhost/databasename --table node --insert nodes.csv
csvsql --db postgresql://user:passwd@localhost/databasename --table link --insert links.csv

 

The parameters are:

  • ● -db <DBURL> The database URL to connect to, in SQLAlchemy format
  • ● –table <TABLENAME> What name should the table get? if not supplied, the CSV filename without extension will be used.
  • ● –insert not only create the CREATE TABLE DDL statement but also insert the data sets into the freshly created table.

This tool has (in my opinion) three small drawbacks:

  1. 1. It doesn’t allow you to see the insert statements. The CREATE TABLE statement will be printed to stdout, if you don’t provide a db URL. But there is no way to see the insert statements.
  2. 2. It can’t handle already existing tables. There is no –add-drop option to issue a DROP TABLE statement in advance to create the new one.
  3. 3. It’s not able to autocreate an ID column. This complicates the first step of creating a usable CSV file to some extend, as you can see above.

So the last action is to create the primary key on the id column in both tables:

alter table node add primary key (id);
alter table link add primary key (id);

 

Even with these little drawbacks the csvkit tool chain has numerous applications. Give it a spin!