Database model
GnrSqlDb needs to know a full set of informations about the database:
- its structure: packages, tables and columns etc.
- relations
We call this set of informations the database model. There are two sides of the model: one is a Bag representation called model.src, it can be loaded or saved as XML file. The second is model.obj which is a hierarchical structure of objects such as tables, columns, records, built using the model.src as a recipe
Model Source
There are three ways to provide model source:
- adding "pieces" of db using the functional sintax of GnrStructures.
mydb = GnrSqlDb(ConnectionParams) pkg = mydb.packageSrc('PackageName') mytable=pkg.table() (...)
- loading the entire model from an XML representation
mydb = GnrSqlDb(ConnectionParams) mydb.loadModelFromXml('/sample.xml')
- importing it automatically from the structure of the db.
mydb = GnrSqlDb(ConnectionParams) mydb.importModelFromDb()
Writing a DbModelSrc in Python
Since we think that writing XML is very boring, the most commonly used way to create a database model is using GnrStructures. In the next example we will create a simple database containing movies, director and dvd. In order to do this we have to write a mixin class and define just one single method called configure. In the configure method we describe the database model.
Adding package
The first element added to the structure is a package item. Our databases must have at least one package as root element. A Package represents a set of tables. The method package adds a Package to the model, it takes as parameters metadata such as comment, name_short, name_long, etc.
pkg = mydb.packageSrc('video',comment='My movie catalog',
name_short='Video',
name_long='Video Catalog',
name_full='John's video catalog')
Adding tables
Then we start adding tables to the package: people, cast, movie, dvd.
table paramethers are:
- param name: table name
- param sqlschema
- param comment: comment about table
- param name_short: name_short
- param name_long: name_long
- param name_full: name_full
- param pkey: the column which is primary key
from config_db method we can add:
#dvd table:
dvd = pkg.table('dvd', name_short='Dvd',name_long='Dvd', name_full='Dvd', pkey='code')
Adding columns
Then we add to each table its columns. (in the example we choose dvd)
column method has these params:
- param name: column name
- param dtype: it can be omitted for text and varchar columns
- param size: string, 'min:max' or fixed lenght 'len'. (If there isn't dtype and size has not ':' eg '30' and dtype is char, if size is like ':30' or '2:30' dtype is varchar)
- param comment: comment about column
- param sqlname
- param name_short: name_short
- param name_long: name_long
- param name_full: name_full
- param default
- param notnull
- param unique
- param indexed
dvd = pkg.table('dvd', name_short='Dvd', name_long='Dvd', pkey='code')
dvd_id = dvd.column('code', 'L')
dvd.column('movie_id', name_short='Mid', name_long='Movie id')
dvd.column('purchasedate', 'D', name_short='Pdt', name_long='Purchase date')
dvd.column('available', name_short='Avl', name_long='Available')
Adding relations
Let's see how to add relations between tables. We want to link the column movie_id of the table dvd with the id of the table movie using movie_id as foreign key.
dvd.column('movie_id').relation('movie.id')
# Note: we can use column method as getter
Adding indexes
To add index to a table.
Params:
- param columns: list, or tuple, or string separated by commas
- param name: index name
- param unique: unicity bound
pkg.table('movie').index('title', 'i_title', unique='y')
# Note: table is used as getter
Python vs. XML
Here is a comparison of python complete source and its XML equivalent
- Python
pkg = mydb.packageSrc('video') pkg.attributes.update(comment='video package',name_short='video', name_long='video', name_full='video') people = pkg.table('people', name_short='people', name_long='People', rowcaption='name,year:%s (%s)', pkey='id') people.column('id', 'L') people.column('name', name_short='N.', name_long='Name') people.column('year', 'L', name_short='Yr', name_long='Birth Year') people.column('nationality', name_short='Ntl',name_long='Nationality') cast = pkg.table('cast', name_short='cast', name_long='Cast', rowcaption='', pkey='id') cast.column('id', 'L') cast.column('movie_id','L', name_short='Mid', name_long='Movie id').relation('movie.id') cast.column('person_id','L',name_short='Prs', name_long='Person id').relation('people.id') cast.column('role', name_short='Rl.',name_long='Role') cast.column('prizes', name_short='Priz.',name_long='Prizes', size='40') movie = pkg.table('movie', name_short='Mv',name_long='Movie', rowcaption='title', pkey='id') movie.column('id', 'L') movie.column('title', name_short='Ttl.',name_long='Title', validate_case='capitalize', validate_len='3,40') movie.index('title', 'i_title', unique='y') movie.column('genre', name_short='Gnr',name_long='Genre', validate_case='upper', validate_len='3,10',indexed='y') movie.column('year', 'L', name_short='Yr',name_long='Year',indexed='y') movie.column('nationality', name_short='Ntl', name_long='Nationality') movie.column('description', name_short='Dsc', name_long='Movie description') dvd = pkg.table('dvd', name_short='Dvd', name_long='Dvd', pkey='code') dvd_id = dvd.column('code', 'L') dvd.column('movie_id', name_short='Mid', name_long='Movie id').relation('movie.id') dvd.column('purchasedate', 'D', name_short='Pdt', name_long='Purchase date') dvd.column('available', name_short='Avl', name_long='Available') - XML:
<?xml version="1.0" encoding="UTF-8"?> <GenRoBag> <packages tag="package_list"> <video name_short="video" comment="video package" tag="package" name_full="video" name_long="video"> <tables tag="table_list"> <people pkey="id" tag="table" rowcaption="name,year:%s (%s)" name_short="people" name_long="People"> <columns tag="column_list"> <id dtype="L" tag="column"/> <name name_long="Name" name_short="N." tag="column"/> <year name_long="Birth Year" dtype="L" name_short="Yr" tag="column"/> <nationality name_long="Nationality" name_short="Ntl" tag="column"/> </columns> </people> <cast pkey="id" tag="table" rowcaption="" name_short="cast" name_long="Cast"> <columns tag="column_list"> <id dtype="L" tag="column"/> <movie_id name_long="Movie id" dtype="L" name_short="Mid" tag="column"> <relation related_column="movie.id" mode="relation"/> </movie_id> <person_id name_long="Person id" dtype="L" name_short="Prs" tag="column"> <relation related_column="people.id" mode="relation"/> </person_id> <role name_long="Role" name_short="Rl." tag="column"/> <prizes name_long="Prizes" name_short="Priz." tag="column" size="40"/> </columns> </cast> <movie pkey="id" tag="table" rowcaption="title" name_short="Mv" name_long="Movie"> <columns tag="column_list"> <id dtype="L" tag="column"/> <title validate_case="capitalize" validate_len="3,40" name_long="Title" name_short="Ttl." tag="column"/> <genre validate_case="upper" validate_len="3,10" name_long="Genre" name_short="Gnr" tag="column" indexed="y"/> <year name_long="Year" dtype="L" name_short="Yr" tag="column" indexed="y"/> <nationality name_long="Nationality" name_short="Ntl" tag="column"/> <description name_long="Movie description" name_short="Dsc" tag="column"/> </columns> <indexes tag="index_list"> <i_title unique="y" tag="index" columns="title"/> </indexes> </movie> <dvd pkey="code" tag="table" name_short="Dvd" name_long="Dvd"> <columns tag="column_list"> <code dtype="L" tag="column"/> <movie_id name_long="Movie id" name_short="Mid" tag="column"> <relation related_column="movie.id" mode="relation"/> </movie_id> <purchasedate name_long="Purchase date" dtype="D" name_short="Pdt" tag="column"/> <available name_long="Available" name_short="Avl" tag="column"/> </columns> </dvd> </tables> </video> </packages> </GenRoBag>
Model Object
When the model.src is defined we can buld the model.obj hierarchy of Sql Objects calling db method startup
mydb.startup()
Attachments
- dbstruct.png (52.6 kB) - added by anonymous 20 months ago.
- db_video_relations.png (50.5 kB) - added by anonymous 20 months ago.
