zope.generations

Software screenshot:
zope.generations
Software detaljer:
Version: 4.0.0 Alpha 1
Upload dato: 15 Apr 15
Licens: Gratis
Popularitet: 2

Rating: nan/5 (Total Votes: 0)

zope.generations giver en metode til opdatering af objekter i databasen, når ansøgningen skemaændringer. & Nbsp; En ansøgning skema er hovedsagelig strukturen af ​​data, struktur af klasser i tilfælde af ZODB eller tabellen beskrivelserne i tilfælde af en relationsdatabase.
detaljeret dokumentation
Generationer er en metode til opdatering af objekter i databasen, når ansøgningen skemaændringer. En ansøgning skema er i det væsentlige strukturen af ​​data, struktur af klasser i tilfælde af ZODB eller tabellen beskrivelser i tilfælde af en relationsdatabase.
Når du ændrer datastrukturer din ansøgning, for eksempel, du ændre den semantiske mening af en eksisterende felt i en klasse, vil du have et problem med databaser, der er oprettet før din ændring. For en mere grundig diskussion og mulige løsninger, se http://wiki.zope.org/zope3/DatabaseGenerations
Vi vil bruge komponentarkitektur, og vi får brug for en database og en forbindelse:
& Nbsp; >>> import cgi
& Nbsp; >>> fra pprint import pprint
& Nbsp; >>> fra zope.interface import- redskaber
& Nbsp; >>> fra ZODB.tests.util import DB
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> root = conn.root ()
Forestil dig, at vores ansøgning er et orakel: du kan lære den at reagere på sætninger. Lad os holde det simpelt og gemme data i en dict:
& Nbsp; >>> root ['svar'] = {'Hello': 'Hi & hvordan gør du',
& Nbsp; ... «? Meningen med livet«: »42«,
& Nbsp; ... »fire & Nbsp; >>> indførselstransaktion
& Nbsp; >>> transaction.commit ()
første opsætning
Her er nogle generationer-specifikke kode. Vi vil skabe og registrere en SchemaManager. SchemaManagers er ansvarlige for den faktiske opdateringer af databasen. Denne ene vil være bare en dummy. Pointen her er at gøre generationerne modul klar over, at vores program understøtter generationer.
Standardværdien gennemførelse af SchemaManager er ikke egnet til denne test, fordi den bruger Python moduler til at styre generationer. For nu, vil det være fint, da vi ikke ønsker det at gøre noget endnu.
& Nbsp; >>> fra zope.generations.interfaces importerer ISchemaManager
& Nbsp; >>> fra zope.generations.generations importerer SchemaManager
& Nbsp; >>> import zope.component
& Nbsp; >>> dummy_manager = SchemaManager (minimum_generation = 0, generation = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... dummy_manager, ISchemaManager, navn = 'some.app ")
»Some.app 'er en unik identifikation. Du skal bruge en URI eller den stiplede navnet på din pakke.
Når du starter Zope og en database åbnes, en begivenhed IDatabaseOpenedWithRoot sendt. Zope registrerer evolveMinimumSubscriber som standard som en handler til denne begivenhed. Lad os simulere denne:
& Nbsp; >>> klasse DatabaseOpenedEventStub (objekt):
& Nbsp; ... def __init __ (self, database):
& Nbsp; ... self.database = database
& Nbsp; >>> begivenhed = DatabaseOpenedEventStub (db)
& Nbsp; >>> fra zope.generations.generations importerer evolveMinimumSubscriber
& Nbsp; >>> evolveMinimumSubscriber (begivenhed)
Konsekvensen af ​​denne aktion er, at nu indeholder databasen, at vores nuværende skema nummer er 0. Når vi opdatere skemaet, vil Zope3 have en idé om, hvad udgangspunktet var. Her ser?
& Nbsp; >>> fra zope.generations.generations importerer generations_key
& Nbsp; >>> rod [generations_key] ['some.app']
& Nbsp; 0
I det virkelige liv, bør du aldrig behøver at bekymre med denne nøgle direkte, men du skal være opmærksom på, at den eksisterer.
Upgrade scenarie
Tilbage til historien. Nogle tiden går, og en af ​​vores kunder bliver hacket, fordi vi har glemt at undslippe HTML specialtegn! Den rædsel! Vi skal løse problemet ASAP uden at miste data. Vi beslutter at bruge generationer at imponere vores kammerater.
Lad os opdatere skemaet manager (droppe den gamle og installere en ny brugerdefineret en):
& Nbsp; >>> fra zope.component import globalregistry
& Nbsp; >>> gsm = globalregistry.getGlobalSiteManager ()
& Nbsp; >>> gsm.unregisterUtility (forudsat = ISchemaManager, navn = 'some.app ")
& Nbsp; Sand
& Nbsp; >>> klasse MySchemaManager (objekt):
& Nbsp; ... instrumenter (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generation = 2
& Nbsp; ...
& Nbsp; ... def udvikle sig (selv, sammenhæng generation):
& Nbsp; ... root = context.connection.root ()
& nbsp; ... svar = root ['svar']
& Nbsp; ... hvis generation == 1:
& Nbsp; ... for spørgsmål, svar i answers.items ():
& Nbsp; ... svar [spørgsmål] = cgi.escape (svar)
& Nbsp; ... Elif generation == 2:
& Nbsp; ... for spørgsmål, svar i answers.items ():
& Nbsp; ... Del svar [spørgsmål]
& Nbsp; ... svar [cgi.escape (spørgsmål)] = svar
& Nbsp; ... andet:
& Nbsp; ... hæve ValueError ("Bummer")
& Nbsp; ... root ['svar'] = svar # ping vedholdenhed
& Nbsp; ... transaction.commit ()
& Nbsp; >>> leder = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manager, ISchemaManager, navn = 'some.app ")
Vi har sat minimum_generation til 1. Det betyder, at vores ansøgning vil nægte at køre med en database ældre end generation 1. attribut Den generation er sat til 2, hvilket betyder, at den nyeste generation, som denne SchemaManager kender er 2.
udvikle sig () er den arbejdshest her. Dens opgave er at få databasen fra generation-1 til generation. Det får en sammenhæng, som har attributten "forbindelse", som er en forbindelse til ZODB. Du kan bruge det til at ændre objekter som i dette eksempel.
I dette særlige generation implementering 1 undslipper svarene (sige, kritiske, fordi de kan indtastes af nogen!), Generation 2 undslipper spørgsmålene (sige, mindre vigtige, da disse kan indtastes af autoriseret personell kun).
Faktisk behøver du ikke virkelig har brug for en tilpasset implementering af ISchemaManager. Den ene er til rådighed, vi har brugt det til en dummy tidligere. Det bruger Python-moduler til afholdelse af Evolver funktioner. Se dens docstrengen for mere information.
I det virkelige liv vil du have meget mere kompleks objektstruktur end den her. For at gøre dit liv lettere, er der to meget nyttige funktioner til rådighed i zope.generations.utility: findObjectsMatching () og findObjectsProviding (). De vil grave gennem containere rekursivt at hjælpe dig opsøge gamle genstande, som du ønsker at opdatere, ved interface eller af nogle andre kriterier. De er nemme at forstå, kontrollere deres docstrings.
Generationer i aktion
Så vores rasende kunde downloader vores nyeste kode og genstarter Zope. Arrangementet bliver automatisk sendt igen:
& Nbsp; >>> begivenhed = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (begivenhed)
Shazam! Klienten er glad igen!
& Nbsp; >>> pprint (root ['svar'])
& Nbsp; {'Hello': "Hi & hvordan gør du?",
& Nbsp; "meningen med livet?«: »42«,
& Nbsp; "fire Fordi evolveMinimumSubscriber er meget doven, det kun opdaterer databasen lige nok til, at din ansøgning kan bruge det (til minimum_generation, der er). , Markøren viser faktisk, at databasen generation er blevet stødte til 1:
& Nbsp; >>> rod [generations_key] ['some.app']
& Nbsp; 1
Vi ser, at generationer arbejder, så vi beslutter at tage det næste skridt og udvikle sig til generation 2. Lad os se, hvordan dette kan gøres manuelt:
& Nbsp; >>> fra zope.generations.generations importerer udvikle sig
& Nbsp; >>> udvikle sig (db)
& Nbsp; >>> pprint (root ['svar'])
& Nbsp; {'Hello': "Hi & hvordan gør du?",
& Nbsp; "meningen med livet?«: »42«,
& Nbsp; "fire & Nbsp; >>> rod [generations_key] ['some.app']
& Nbsp; 2
Standard adfærd Evolve opgraderinger til den nyeste generation, som den SchemaManager. Du kan bruge hvordan argument for at udvikle sig (), når du vil bare kontrollere, om du har brug for at opdatere eller hvis du ønsker at være doven ligesom abonnenten, som vi har kaldt tidligere.
Bestilling af skema ledere
Ofte undersystemer bruges til at komponere en applikation stole på andre delsystemer til at fungere ordentligt. Hvis begge delsystemer giver skema ledere, er det ofte nyttigt at vide, i hvilken rækkefølge de evolvers vil blive kaldt. Dette giver mulighed for en ramme, og det er kunderne til at kunne udvikle sig i koncerten, og kunderne kan vide, at rammen bliver udviklet før eller efter sig selv.
Dette kan opnås ved at styre navnene på de skema udlejer forsyningsselskaber. Skemaet ledere køres i den rækkefølge bestemmes ved at sortere deres navne.
& Nbsp; >>> manager1 = SchemaManager (minimum_generation = 0, generation = 0)
& Nbsp; >>> manager2 = SchemaManager (minimum_generation = 0, generation = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, navn = 'another.app ")
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, name = "another.app-udvidelse")
Bemærk, hvordan navnet på den første pakke bruges til at oprette et namespace for afhængige pakker. Dette er ikke et krav i rammerne, men en bekvem mønster for denne brug.
Lad os udvikle databasen for at etablere disse generationer:
& Nbsp; >>> begivenhed = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (begivenhed)
& Nbsp; >>> rod [generations_key] ['another.app']
& Nbsp; 0
& Nbsp; >>> rod [generations_key] ['another.app-udvidelse «]
& Nbsp; 0
Lad os antage, at en eller anden grund hvert delsystem brug for at tilføje en generation, og den generation 1 af 'another.app-udvidelse «afhænger generation 1 af' another.app«. Vi bliver nødt til at give skema managers for hver at post, de har været kørt, så vi kan kontrollere resultatet:
& Nbsp; >>> gsm.unregisterUtility (forudsat = ISchemaManager, navn = 'another.app ")
& Nbsp; Sand
& Nbsp; >>> gsm.unregisterUtility (
& Nbsp; ... forudsat = ISchemaManager, name = "another.app-udvidelse")
& Nbsp; Sand
& Nbsp; >>> klasse FoundationSchemaManager (objekt):
& Nbsp; ... instrumenter (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generation = 1
& Nbsp; ...
& Nbsp; ... def udvikle sig (selv, sammenhæng generation):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... bestilling = root.get ("bestilling", [])
& Nbsp; ... hvis generation == 1:
& Nbsp; ... ordering.append ("fundament 1 ')
& Nbsp; ... print 'fundament generation 1'
& Nbsp; ... andet:
& Nbsp; ... hæve ValueError ("Bummer")
& Nbsp; ... root ['bestilling'] = bestilling # ping vedholdenhed
& Nbsp; ... transaction.commit ()
& Nbsp; >>> klasse DependentSchemaManager (objekt):
& Nbsp; ... instrumenter (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generation = 1
& Nbsp; ...
& Nbsp; ... def udvikle sig (selv, sammenhæng generation):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... bestilling = root.get ("bestilling", [])
& Nbsp; ... hvis generation == 1:
& Nbsp; ... ordering.append (afhængig 1 ')
& Nbsp; ... print 'afhængig generation 1'
& Nbsp; ... andet:
& Nbsp; ... hæve ValueError ("Bummer")
& Nbsp; ... root ['bestilling'] = bestilling # ping vedholdenhed
& Nbsp; ... transaction.commit ()
& Nbsp; >>> manager1 = FoundationSchemaManager ()
& Nbsp; >>> manager2 = DependentSchemaManager ()
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, navn = 'another.app ")
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, name = "another.app-udvidelse")
Evolving databasen nu vil altid køre den "another.app" Evolver før 'another.app-udvidelse «Evolver:
& Nbsp; >>> begivenhed = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (begivenhed)
& Nbsp; fundament generation 1
& Nbsp; afhængig generation 1
& Nbsp; >>> root ['bestilling']
& Nbsp; ['fundament 1', 'afhængige 1']
Installation
I det ovenstående eksempel, vi manuelt initialiseret svarene. Vi skal ikke gøre det manuelt. Ansøgningen bør være i stand til at gøre det automatisk.
IInstallableSchemaManager udvider ISchemaManager, giver en installation metode til udførelse af en intial installation af en ansøgning. Det er et bedre alternativ end at registrere database åbnede abonnenter.
Lad os definere en ny skema manager, der omfatter installation:
& Nbsp; >>> gsm.unregisterUtility (forudsat = ISchemaManager, navn = 'some.app ")
& Nbsp; Sand
& Nbsp; >>> fra zope.generations.interfaces importerer IInstallableSchemaManager
& Nbsp; >>> klasse MySchemaManager (objekt):
& Nbsp; ... instrumenter (IInstallableSchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generation = 2
& Nbsp; ...
& Nbsp; ... def installere (self, kontekst):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... root ['svar'] = {'Hello': 'Hi & hvordan gør du',
& Nbsp; ... «? Meningen med livet«: »42«,
& Nbsp; ... »fire & Nbsp; ... transaction.commit ()
& Nbsp; ...
& Nbsp; ... def udvikle sig (selv, sammenhæng generation):
& Nbsp; ... root = context.connection.root ()
& nbsp; ... svar = root ['svar']
& Nbsp; ... hvis generation == 1:
& Nbsp; ... for spørgsmål, svar i answers.items ():
& Nbsp; ... svar [spørgsmål] = cgi.escape (svar)
& Nbsp; ... Elif generation == 2:
& Nbsp; ... for spørgsmål, svar i answers.items ():
& Nbsp; ... Del svar [spørgsmål]
& Nbsp; ... svar [cgi.escape (spørgsmål)] = svar
& Nbsp; ... andet:
& Nbsp; ... hæve ValueError ("Bummer")
& Nbsp; ... root ['svar'] = svar # ping vedholdenhed
& Nbsp; ... transaction.commit ()
& Nbsp; >>> leder = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manager, ISchemaManager, navn = 'some.app ")
Nu lader åbne en ny database:
& Nbsp; >>> db.close ()
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> 'svar «i conn.root ()
& Nbsp; False
& Nbsp; >>> begivenhed = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (begivenhed)
& Nbsp; >>> conn.sync ()
& Nbsp; >>> root = conn.root ()
& Nbsp; >>> pprint (root ['svar'])
& Nbsp; {'Hello': "Hi & hvordan gør du?",
& Nbsp; "meningen med livet?«: »42«,
& Nbsp; "fire & Nbsp; >>> rod [generations_key] ['some.app']
& Nbsp; 2
Den ZODB transaktionsjournal bemærker, at vores install script blev henrettet
& Nbsp; >>> [. It.description for det i conn.db () storage.iterator ()] [- 2]
& Nbsp; u'some.app: kører installere generation '
(Minor bemærkning: det er ikke den sidste post, fordi der er to begår: MySchemaManager udfører en, og evolveMinimumSubscriber udfører den anden MySchemaManager ikke virkelig har brug for at begå.).

Hvad er nyt i denne udgivelse:.

  • Tilføjet understøttelse af Python 3.3
  • Erstattet frarådet zope.interface.implements forbrug med tilsvarende zope.interface.implementer dekoratør.
  • Faldt støtte til Python 2.4 og 2.5.

Hvad er nyt i version 3.7.1:

  • Fjernet udbygningsblok del, som blev anvendt under udvikling, men gør ikke kompilere på Windows.
  • Generation scripts tilføje en transaktion note.

Krav :

  • Python

Andre software developer Zope Corporation and Contributors

zope.browsermenu
zope.browsermenu

20 Feb 15

zope.app.http
zope.app.http

11 May 15

zope.app.server
zope.app.server

11 May 15

zope.pagetemplate
zope.pagetemplate

11 May 15

Kommentarer til zope.generations

Kommentarer ikke fundet
Tilføj kommentar
Tænd billeder!