[Python] slides genrobag e genrosql

Giovanni Porcari giovanni.porcari a softwell.it
Dom 27 Set 2015 21:35:15 CEST


> Il giorno 27/set/2015, alle ore 16:59, Massimo Masson <max a studiomasson.it> ha scritto:
> 
> Il 27/09/2015 14.18, Giovanni Porcari ha scritto:
> [...]
>> https://www.dropbox.com/s/qme8cm0gqd8ihoj/documenti%20genropy.zip?dl=0
> [...]
> 
> Grazie Giovanni!
> 
> Ora guardo un po' meglio, c'era almeno un pattern per usare le relazioni in genrosql che mi è risultato abbastanza nuovo anche concettualmente, il modo in cui "navighi" le relazioni per riferimento in modo semplice... mi pare fosse quello con l'uso del "@" ma forse sto facendo confusione..

Caro Massimo
ammetto che forse abbiamo detto troppe cose ma ora cerco di farti un piccolo riepilogo
su come accedere ad un db con gnrsql.

Siccome parliamo di Sql ci serve un database e ti suggerisco di usare il db
che puoi trovare a 'https://chinookdatabase.codeplex.com'.

Citando il sito :"Chinook is a sample database available for SQL Server, Oracle, MySQL, etc. It can be created by running a single SQL script.
Chinook database is an alternative to the Northwind database, being ideal for demos and testing 
ORM tools targeting single and multiple database servers.”

Il link diretto alla versione sqlite è questo:
https://chinookdatabase.codeplex.com/downloads/get/557773

Una volta scaricato il db (e installato Genropy da Github o da Bitbucket)
puoi aprire un IDE python o digitare python nel terminale.

Dovremo importare GnrSqlDb:

>>> from gnr.sql.gnrsql import GnrSqlDb
>>> 

Ora creiamo un istanza del db:

>>>db=GnrSqlDb(dbname=’directory_dove_hai_scaricato/Chinook_Sqlite.sqlite’)
>>>

Siccome stiamo lavorando su un db non definito da noi lanciamo il comando
per leggere la struttura:
>>>db.importModelFromDb()
>>>

a questo punto devi avviare il db con:

>>> db.startup()
>>> 

Ora il db è pronto e per prima cosa possiamo interrogare la sua struttura che è
contenuta a db.packages

>>> dbstruct=db.packages

>>> dbstruct.keys()
[u'main']


>>> main_struct = dbstruct['main']

Prendiamo l'elenco delle tabelle:
>>>['%s : %s' % (table_code,table.name) for table_code,table in main_struct.tables.items()]
[u'album : Album', u'artist : Artist', u'customer : Customer', u'employee : Employee', u'genre : Genre', u'invoice : Invoice', u'invoiceline : InvoiceLine', u'mediatype : MediaType', u'playlist : Playlist', u'playlisttrack : PlaylistTrack', u'track : Track']

Ora prendiamo l'elenco delle colonne di 'album':
>>>{column_code:column.name for column_code,column in main_struct.table('album').columns.items()}
[u'albumid : AlbumId', u'title : Title', u'artistid : ArtistId']

Adesso iteriamo sulle colonne di tutte le tabelle:

for table_code,table in main_struct.tables.items():
   print '   code: %s\n   name: %s\ncolumns: %s\n' % ( table_code,table.name,{column_code:column.name for column_code,column in main_struct.table(table_code).columns.items()})

  
   code: album
   name: Album
columns: {u'albumid': u'AlbumId', u'artistid': u'ArtistId', u'title': u'Title'}

   code: artist
   name: Artist
columns: {u'artistid': u'ArtistId', u'name': u'Name'}

   code: customer
   name: Customer
columns: {u'city': u'City', u'fax': u'Fax', u'firstname': u'FirstName', u'supportrepid': u'SupportRepId', u'lastname': u'LastName', u'company': u'Company', u'email': u'Email', u'phone': u'Phone', u'state': u'State', u'address': u'Address', u'postalcode': u'PostalCode', u'country': u'Country', u'customerid': u'CustomerId'}

   code: employee
   name: Employee
columns: {u'city': u'City', u'fax': u'Fax', u'employeeid': u'EmployeeId', u'firstname': u'FirstName', u'title': u'Title', u'lastname': u'LastName', u'reportsto': u'ReportsTo', u'birthdate': u'BirthDate', u'phone': u'Phone', u'state': u'State', u'address': u'Address', u'postalcode': u'PostalCode', u'hiredate': u'HireDate', u'country': u'Country', u'email': u'Email'}

   code: genre
   name: Genre
columns: {u'genreid': u'GenreId', u'name': u'Name'}

   code: invoice
   name: Invoice
columns: {u'invoiceid': u'InvoiceId', u'billingpostalcode': u'BillingPostalCode', u'invoicedate': u'InvoiceDate', u'billingstate': u'BillingState', u'billingaddress': u'BillingAddress', u'billingcountry': u'BillingCountry', u'total': u'Total', u'customerid': u'CustomerId', u'billingcity': u'BillingCity'}

   code: invoiceline
   name: InvoiceLine
columns: {u'invoicelineid': u'InvoiceLineId', u'invoiceid': u'InvoiceId', u'unitprice': u'UnitPrice', u'quantity': u'Quantity', u'trackid': u'TrackId'}

   code: mediatype
   name: MediaType
columns: {u'mediatypeid': u'MediaTypeId', u'name': u'Name'}

   code: playlist
   name: Playlist
columns: {u'playlistid': u'PlaylistId', u'name': u'Name'}

   code: playlisttrack
   name: PlaylistTrack
columns: {u'trackid': u'TrackId', '_multikey': '_multikey', u'playlistid': u'PlaylistId'}

   code: track
   name: Track
columns: {u'mediatypeid': u'MediaTypeId', u'name': u'Name', u'trackid': u'TrackId', u'bytes': u'Bytes', u'albumid': u'AlbumId', u'composer': u'Composer', u'genreid': u'GenreId', u'unitprice': u'UnitPrice', u'milliseconds': u'Milliseconds'}


Ora se vuoi fare una query (ad esempio su album) ci prendiamo la tabella album

>>> album=db.table('main.album')
>>> album.query(limit=10).fetch()
[[AlbumId=1,Title=For Those About To Rock We Salute You,ArtistId=1,pkey=1], [AlbumId=2,Title=Balls to the Wall,ArtistId=2,pkey=2], [AlbumId=3,Title=Restless and Wild,ArtistId=2,pkey=3], [AlbumId=4,Title=Let There Be Rock,ArtistId=1,pkey=4], [AlbumId=5,Title=Big Ones,ArtistId=3,pkey=5], [AlbumId=6,Title=Jagged Little Pill,ArtistId=4,pkey=6], [AlbumId=7,Title=Facelift,ArtistId=5,pkey=7], [AlbumId=8,Title=Warner 25 Anos,ArtistId=6,pkey=8], [AlbumId=9,Title=Plays Metallica By Four Cellos,ArtistId=7,pkey=9], [AlbumId=10,Title=Audioslave,ArtistId=8,pkey=10]]

Noterai che abbiamo fatto una query ponendo il parametro limit. In pratica si possono usare le clausole SQL con un '_' al posto dello spazio.
Quindi 'order by' diventa 'order_by'.

Per dire le colonne desiderate puoi usare il parametero columns:

>>> album.query(columns='$Title, a ArtistId.Name',limit=5).fetch()
[[Title=For Those About To Rock We Salute You,_ArtistId_Name=AC/DC,pkey=1], [Title=Balls to the Wall,_ArtistId_Name=Accept,pkey=2], [Title=Restless and Wild,_ArtistId_Name=Accept,pkey=3], [Title=Let There Be Rock,_ArtistId_Name=AC/DC,pkey=4], [Title=Big Ones,_ArtistId_Name=Aerosmith,pkey=5]]

Noterai che le colonne della tabella sono prefissate da '$' mentre le colonne da tabelle in relazione
hanno un nome che inizia con '@'.

Facciamo ora un esempio più complesso :
>>>track_table=db.table('main.track')

>>>track_table.query(columns="""@AlbumId. a ArtistId.Name as Artist, 
                                @AlbumId.Title as Album,
                                $Name,
                                @GenreId.Name as Genre,
                                $Milliseconds""", 
                       where="""@AlbumId. a ArtistId.Name=:artistname 
                                AND
                               $Milliseconds>:ms""",
                   artistname='Metallica',
                             ms=500000,
                             order_by='$Milliseconds desc').fetch()

[[Artist=Metallica,Album=Garage Inc. (Disc 1),Name=Mercyful Fate,Genre=Metal,Milliseconds=671712,pkey=414], [Artist=Metallica,Album=Load,Name=The Outlaw Torn,Genre=Metal,Milliseconds=588721,pkey=1852], [Artist=Metallica,Album=...And Justice For All,Name=To Live Is To Die,Genre=Metal,Milliseconds=588564,pkey=1900], [Artist=Metallica,Album=...And Justice For All,Name=...And Justice For All,Genre=Metal,Milliseconds=585769,pkey=1894], [Artist=Metallica,Album=Garage Inc. (Disc 1),Name=Tuesday's Gone,Genre=Metal,Milliseconds=545750,pkey=417], [Artist=Metallica,Album=Ride The Lightning,Name=The Call Of Ktulu,Genre=Metal,Milliseconds=534883,pkey=1881], [Artist=Metallica,Album=St. Anger,Name=All Within My Hands,Genre=Metal,Milliseconds=527986,pkey=1892], [Artist=Metallica,Album=Master Of Puppets,Name=Master Of Puppets,Genre=Metal,Milliseconds=515239,pkey=1854], [Artist=Metallica,Album=St. Anger,Name=Invisible Kid,Genre=Metal,Milliseconds=510197,pkey=1886], [Artist=Metallica,Album=St. Anger,Name=Some Kind Of Monster,Genre=Metal,Milliseconds=505626,pkey=1884], [Artist=Metallica,Album=Master Of Puppets,Name=Orion,Genre=Metal,Milliseconds=500062,pkey=1859]]

Insomma col path di relazione ti eviti le join e accedere al db è molto semplice.

Spero di averti chiarito un po' di dubbi :)


Ciao

G






Maggiori informazioni sulla lista Python