er-modelling mit zms: das zmssqldb-objekt · pdf filehoffmann+liebenberg gesellschaft für...
TRANSCRIPT
HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Folie: 1
ER-Modelling mit ZMS:Das ZMS SQLDB-Objekt
Dr. Frank Hoffmann / Python User Group Berlin 18.06.2009
Folie: 2HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
ZMS - Zope-basiertes Open-Source-Redaktionssystemfür das STM-Publishing
Folie: 3HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Architektur: ZMS ist ein Zope-Produkt
ZOPE
DTML Python
ZMS
ZOPE
ZO
PE-A
rchitek
tur
* m
ehr
daz
u u
nte
r: h
ttp:/
/ww
w.z
ope.
org
Folie: 4HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Einfaches Content-Modell:Container und Content-Objekte
Ordner
Root
Dokument
Textabschnitt
Abbildung
Tabelle
Linksammlung
Teaser
Teaserelement
Systemfolder
ZMSSQLDB
Folie: 5HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Hintergrund SQL-Einbindung ins Redaktionssystem
Vorhandene Datenbanken ins CMS einbinden
Tabellenartige, nicht-hierarische Inhalte größeren Ausmaßes performant bearbeiten/publizieren
Kein System/GUI-Wechsel
Zielgruppe: Redakteure, CMS-Admins (keine Entwickler)
Soll „konfigurierbar“ sein – weitgehend ohne Programmierung
Redaktionelle Datenbearbeitung steht im Vordergrund
Folie: 6HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Ziel: Zugriff wie im SQL-Browser – plus Relationen!
Folie: 7HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Installationsvoraussetzungen
Python-SQL-Datenbank-Connector, z.B. Python-MySQL
Zope-SQL-DB-Adapter, z.B. ZMySQLDA-Product
Instanziieren eines DB-Adapter-Objektes
Folie: 8HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Tabellen-Repräsentation automatisch per getEntities() erzeugt
Default ist optimiert für MySQL, Beispielvorlagen für Oracle oder PostGres
getEntities() liest Systemtabellen und erzeugt per DB-Connectiondas für ZMS normalisierte Tabellenbeschreibungs-Model
Als Liste von Dictionaries:1. type2. id3. label4. columns: name, label, id, key nullable, type, sort, index, mandatory
Hinweis: die in der Zope-Hierachie eingesetzte getEnties() wird in der Art" 'getEnties‘ + DB-Connector-ID“ benamt (ohne Punkt und Komma!)
Folie: 9HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Anlegen eines ZMSSQLDB-Objektes
Folie: 10HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Konfiguration des Datenmodells
Folie: 11HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Konfiguration des Datenmodells
Folie: 12HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Automatische GUI-Elemente: Was man üblicherweise braucht
PrimitivePrimärschlüssel (PK)StringText / Richtext / htmlDatum/ZeitIntPasswortURL
Komplex (FK-Beziehungen)Select (1:n)Multiselect (n:m)Multimultiselect (n:m:o)Blob (Binärdaten-Referenz)Details (Sub-Tabellen)
Darstellungs-VariantenLazy (Select-Popup für große Auswahlen)Editable (Selectlist-Items direkt erweitern)
TabellentypenTableIntersectionHidden
TabellenspezifischeGUI-Erweiterungen
InterfaceFilter
Folie: 13HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Flexibel editierbar
Ergänzung für GUI-Erweiterung per JS/jquery
ER-Modell per XML
Folie: 14HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Beispiel Automatische GUI-Elemente
1. PK
2. Text
3. Blob
4. Multiselect
5. Select
6. Details
Folie: 15HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Blob-Element: Typ image und file
Blob-Element ist String (Dateiname)
Zwei Typentype=imagetype=file
Zwei Datenablage-Optionenpath = lokalen Verzeichnispfad*remote = URL des entfernten ZMSSQLDB-Objektes
Remote-Option: anstatt lokalem Pfad wird das Binary über das remote-ZMSSQLDB-Objekt gezogen (für Multisites bzw. Site-übergreifende DBs)
...
<item type="dictionary">
<dictionary>
<item key="auto"></item>
<item key="blob" type="dictionary">
<dictionary>
<item key="type"><![CDATA[image]]></item>
<item key="path"><![CDATA[/home/var/CDbase]]></item>
<!-- <item key="remote">http://www.test.de/e3681/e13473</item> -->
</dictionary>
</item>
<item key="hide" type="int">0</item>
<item key="id"><![CDATA[cd_cover]]></item>
<item key="index" type="int">2</item>
<item key="label"><![CDATA[Cover]]></item>
</dictionary>
</item>
...
* WICHTIGER HINWEIS: Das lokale Verzeichnis muss in der ZMS-Config per Option „localFSread“ freigegeben werden
A. Konfigurations-GUI
B. Redaktions-GUI
Folie: 16HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Besonderes GUI-Element: Multi-Multi-Select („n:m:o“)
ER-Modell Ausschnitt: Person hat diverse Arbeitpakete und dort jeweils eine definierte Rolle
Konfigurations-GUI
Automatisches Redaktions-GUI
Folie: 17HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Besonderes GUI-Element: mysqlset
...
<item>
<dictionary>
<item key="id">cdMedium</item><item key="label">Medium</item><item key="pk" type="int">0</item><item key="auto" type="int">0</item><item key="hide" type="int">1</item><item key="multiselect">
<dictionary>
<item key="mysqlset" type="int">1</item>
</dictionary>
</item>
</dictionary>
</item>
...
Folie: 18HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Code-Beispiel GUI-Element: Interface
1. Vorschau-Bild auf Größe begrenzen2. Vollansicht im neuen Fenster per Mausklick...
<item key="interface"><![CDATA[
<script type="text/javascript">
$(document).ready(function(){
$("#tr_cd_cover table.neutralColorBlack img").attr({title:"Klick zum Vergrößern ..."} );
$("#tr_cd_cover table.neutralColorBlack img").click( function() {
window.open( $("#tr_cd_cover table.neutralColorBlack img").attr('src') );return false; } );
})
</script>
<style type="text/css">
tr#tr_cd_cover table.neutralColorBlack {
margin-right:30px;
margin-left:25px;
}
tr#tr_cd_cover table.neutralColorBlack img {
width:120px;
}
</style>]]>
</item>
...
Folie: 19HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Beispiel GUI-Element: Interface (Interaktive Datenvalidierung)
Folie: 20HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Beispiel-Code Interaktive Daten-Validierung
------------------------------------------------------
[1] SQLMODEL: jQuery Ajax-Script ersetzt DOM-Element
------------------------------------------------------
....
<item key="interface"><![CDATA[<scripttype="text/javascript">
$(document).ready(function(){
$('#new_email').bind('change', function(){
if ( $('#new_email').attr('value') !=
$('input[name=old_email]').attr('value') ) {
$('#info_email').load('sql_validate_email_ajax', { 'test':
$('#new_email').attr('value') });
} else {
$('#info_email').empty();
}
});
});
...
-------------------------------------------------------
[2] DTML: sql_validate_email_ajax liefert feedback
--------------------------------------------------------
<dtml-let t="REQUEST.get('test','')">
<dtml-if t>
<dtml-in "_['objMap']['datasource'].query('SELECT * FROM persons WHERE email=\'%s\' '%(t))['records']" mapping>
<span style="color:red;font-weight:bold;text-decoration: blink">ERROR: Email alreadyexists.</span>
<dtml-else>
<span style="color:green;font-weight:bold;">Emailcheck OK.</span>
</dtml-in>
</dtml-if>
</dtml-let>
Folie: 21HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Filter-Element: erweitert SQL-Klausel der Übersichtstabelle
Typischer Einsatz:Multisites, die auf ein
einziges SQL-Repository
zugreifen
Beispiel:<item key="filter"><![CDATA[
<dtml-if
"getParentNode().getObjProperty('ensemblefilter',
REQUEST)">eventEnsemble IN ('<dtml-var
"getParentNode().getObjProperty('ensemblefilter',
REQUEST)">')
</dtml-if>
]]></item>
Beispiel:<item key="filter"><![CDATA[
<dtml-if
"getParentNode().getObjProperty('ensemblefilter',
REQUEST)">eventEnsemble IN ('<dtml-var
"getParentNode().getObjProperty('ensemblefilter',
REQUEST)">')
</dtml-if>
]]></item>
Folie: 22HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Web-Maske
Folie: 23HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
Methoden-Struktur für die Masken-PräsentationAnm: Felder lassen sich ausschließen per REQUEST-Variable ZMS_EXCLUDE_IDS [Liste]
<!-- ### FORMVARIABLES -->
<!-- ### IDENTIFYING VALUES: Voraussetzung PK = 1. Spalte -->
<!-- ### Select User-Datatset by ZSQL-Method -->
<dtml-if "_.len(row)>0">
<!-- ### UPDATE: Dataset already exists! ### -->
<dtml-call "REQUEST.set('ZMS_ACTION','update')">
<dtml-call "REQUEST.set('rowid',row[0][0])">
<dtml-call "REQUEST.set(primary_key,rowid)">
<!-- ### SQL STATEMENT -->
<dtml-call "REQUEST.set('sqlStatement',[])"
><dtml-call "sqlStatement.append('SELECT * FROM %s '%SESSION[sessqentitykey])"
><dtml-call "sqlStatement.append('WHERE ' + primary_key + '=' + sql_quote__(SESSION[sessqentitykey],primary_key,rowid))"
><dtml-call "REQUEST.set('resSlctStmnt',''.join(sqlStatement))"
><dtml-call "REQUEST.set('res',query(resSlctStmnt)['records'])">
<!-- ### INPUT FORM GENERATION / ACTION -->
<dtml-in res
><dtml-call "recordSet_Init(REQUEST)"
><dtml-call "writeBlock('[input_profil] %s qentitykey: %s, %s=%s'%(actions,qentitykey,primary_key,rowid))"
><dtml-var actions>
</dtml-in>
<dtml-else>
<!-- ### INSERT: New Dataset ### -->
<dtml-call "REQUEST.set('ZMS_ACTION','insert')">
<dtml-call "REQUEST.set('rowid',-1)">
<dtml-call "recordSet_Init(REQUEST)">
<dtml-call"SESSION.set('ZMS_ROWID',REQUEST.get('new_username',_.None))">
<dtml-var actions>
</dtml-if>
</dtml-let>
</dtml-with>
http://eln.zms-hosting.com:8080/sites/UCT/register_form/manage_main
Folie: 24HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
LIVE-Demo Beispiel-Datenbank: CD-Sammlung
Folie: 25HOFFMANN+LIEBENBERGGesellschaft für Informationsmanagement mbH
ANHANG: Anwendungsbeispiel Userdatenbank
ZMSSQLDB
Systemfolder
ZSQL
DTML