zope.generations

Software screenshot:
zope.generations
Podrobnosti Software:
Verze: 4.0.0 Alpha 1
Datum uploadu: 15 Apr 15
Licence: Volný
Popularita: 37

Rating: nan/5 (Total Votes: 0)

zope.generations poskytuje způsob aktualizace objektů v databázi při změně aplikace schématu. & Nbsp; schéma aplikace je v podstatě struktura dat, struktura tříd v případě ZODB nebo popisů tabulky v případě relační databáze.
Podrobná dokumentace
Generace jsou způsob aktualizace objektů v databázi při změně aplikace schématu. Schéma aplikace je v podstatě struktura dat, struktura tříd v případě ZODB nebo popisů tabulky v případě relační databázi.
Při změně datové struktury, vaše aplikace, například změnit sémantický význam existující pole ve třídě, budete mít problém s databází, které byly vytvořeny před změnou. Pro důkladnější diskuse a možných řešení, viz http://wiki.zope.org/zope3/DatabaseGenerations
Budeme používat architekturu komponenty, a budeme potřebovat databázi a připojení:
& Nbsp; >>> import cgi
& Nbsp; >>> od pprint dovozu pprint
& Nbsp; >>> od zope.interface dovozních nářadí
& Nbsp; >>> od ZODB.tests.util import DB
& Nbsp; >>> db = DB ()
& Nbsp; >>> Conn = db.open ()
& Nbsp; >>> root = conn.root ()
Představte si, že naše aplikace je věštec: můžete naučit ho reagovat na fráze. Pojďme aby to jednoduché a ukládat data v dict:
& Nbsp; >>> kořenové ['odpovědi'] = {'Hello': "Ahoj a jak to děláte,",
& Nbsp; ... "? Smyslu života": "42",
& Nbsp; ... "čtyři & Nbsp; >>> import transakce
& Nbsp; >>> transaction.commit ()
Výchozí nastavení
Zde je několik generací specifické code. Budeme vytvářet a zaregistrovat SchemaManager. SchemaManagers jsou odpovědné za skutečné aktualizace databáze. Ten bude jen atrapa. Pointa je, aby generace, modul si vědomi, že naše aplikace podporuje generace.
Výchozí implementace SchemaManager není vhodný pro tuto zkoušku, protože používá Python moduly pro správu generace. Pro tuto chvíli, to bude v pohodě, protože nechceme, aby nic dělat ještě ne.
& Nbsp; >>> od zope.generations.interfaces import ISchemaManager
& Nbsp; >>> od zope.generations.generations import SchemaManager
& Nbsp; >>> import zope.component
& Nbsp; >>> dummy_manager = SchemaManager (minimum_generation = 0, generace = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... dummy_manager, ISchemaManager, name = "some.app")
"Some.app" je jedinečný identifikátor. Měli byste používat URI nebo tečkované jméno vašeho balíčku.
Při spuštění Zope a otevření databáze, IDatabaseOpenedWithRoot událost je odeslána. Zope registruje evolveMinimumSubscriber standardně jako handler pro tuto událost. Pojďme simulovat:
& Nbsp; >>> třída DatabaseOpenedEventStub (objekt):
& Nbsp; ... def __init __ (self, databáze):
& Nbsp; ... self.database = databáze
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> od zope.generations.generations import evolveMinimumSubscriber
& Nbsp; >>> evolveMinimumSubscriber (event)
Důsledkem této akce je, že teď databáze obsahuje skutečnost, že náš současný počet schématu 0. Když jsme aktualizaci schématu, Zope3 bude mít představu o tom, co byl výchozí bod. Tady, vidíš?
& Nbsp; >>> od zope.generations.generations import generations_key
& Nbsp; >>> kořen [generations_key] ['some.app']
& Nbsp; 0
V reálném životě nikdy byste neměli muset obtěžovat s tímto klíčem přímo, ale měli byste si být vědomi toho, že to existuje.
scénář Aktualizace
Zpět k příběhu. Nějaký čas projde a jeden z našich klientů dostane hacknut, protože jsme zapomněli uniknout speciální znaky HTML! Hrůza! Musíme tento problém vyřešit co nejrychleji, aniž by došlo ke ztrátě dat. Rozhodli jsme se využít generace zapůsobit na své vrstevníky.
Pojďme aktualizujte správce schématu (pokles staré a nainstalovat novou vlastní jednu možnost):
& Nbsp; >>> od zope.component dovozu globalregistry
& Nbsp; >>> gsm = globalregistry.getGlobalSiteManager ()
& Nbsp; >>> gsm.unregisterUtility (za předpokladu = ISchemaManager, name = "some.app")
& Nbsp; pravda
& Nbsp; >>> třída MySchemaManager (objekt):
& Nbsp; ... nářadí (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generace = 2
& Nbsp; ...
& Nbsp; ... def vyvíjet (self, kontext, generace):
& Nbsp; ... root = context.connection.root ()
& nbsp; ... odpovědi = root ['odpovědi']
& Nbsp; ... pokud generace == 1:
& Nbsp; ... na otázku, odpověď v answers.items ():
& Nbsp; ... odpovědi [test] = cgi.escape (odpověď)
& Nbsp; ... elif generace == 2:
& Nbsp; ... na otázku, odpověď v answers.items ():
& Nbsp; ... del odpovědi [test]
& Nbsp; ... odpovědi [cgi.escape (otázka)] = odpověď
& Nbsp; ... jinak:
& Nbsp; ... zvýšit ValueError ("průšvih")
& Nbsp; ... kořen ['odpovědi'] = odpovědi # ping trvalost
& Nbsp; ... transaction.commit ()
& Nbsp; >>> manager = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manažer, ISchemaManager, name = "some.app")
Stanovili jsme si minimum_generation na 1. To znamená, že naše žádost odmítne spustit s databází starší než generace 1. atribut generace je nastavena na hodnotu 2, což znamená, že nejnovější generace, která to SchemaManager ví o je 2.
vyvinout () je dříč sem. Jejím úkolem je dostat se do databáze z generace-1 na generaci. To dostane kontext, který má atribut "spojení", což je spojení s ZODB. Můžete ji využít ke změně objekty, jako v tomto případě.
V tomto konkrétním provádění generace 1 uniká odpovědi (řekněme důležité, protože mohou být zadána kýmkoliv!), Generace 2 uniká otázky (řekněme, méně důležité, protože ty mohou být zadány autorizovaný Personální pouze).
Ve skutečnosti, nemáte opravdu potřebují vlastní implementaci ISchemaManager. Jedním z nich je k dispozici, jsme použili ji na figuríny dříve. Používá Python moduly pro organizaci Evolver funkcí. Viz jeho dokumentačního řetězce pro více informací.
V reálném životě, budete mít mnohem složitější objekt struktur, než ten zde. Chcete-li, aby váš život jednodušší, jsou k dispozici v zope.generations.utility dvě velmi užitečné funkce: findObjectsMatching () a findObjectsProviding (). Budou hrabat kontejnerů rekurzivně které vám pomohou hledat staré objekty, které chcete aktualizovat, a rozhraní, nebo jiných kritérií. Jsou snadno pochopit, kontrolovat jejich docstrings.
Generace v akci
Takže náš zuřivý zákazník stáhne naše nejnovější kód a restartuje Zope. Akce je automaticky odeslána znovu:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
Shazam! Klient je zase šťastná!
& Nbsp; >>> pprint (kořenové ['odpovědi'])
& Nbsp; {"Hello": "Ahoj a jak to děláte?",
& Nbsp; "smysl života?": "42",
& Nbsp; "čtyři Vzhledem k tomu, evolveMinimumSubscriber je velmi líný, jen aktualizuje databázi jen tolik, že vaše aplikace může použít (na minimum_generation, že je). Ve skutečnosti, značka označuje, že generace databáze byla narazil do 1:
& Nbsp; >>> kořen [generations_key] ['some.app']
& Nbsp; 1
Vidíme, že generace pracují, tak jsme se rozhodli udělat další krok a vyvíjet na generaci 2. Podívejme se, jak to lze provést ručně:
& Nbsp; >>> od zope.generations.generations import vyvíjet
& Nbsp; >>> vyvinout (db)
& Nbsp; >>> pprint (kořenové ['odpovědi'])
& Nbsp; {"Hello": "Ahoj a jak to děláte?",
& Nbsp; "smysl života?": "42",
& Nbsp; "čtyři & Nbsp; >>> kořen [generations_key] ['some.app']
& Nbsp; 2
Výchozí chování vyvíjet upgrade na nejnovější generaci poskytované SchemaManager. Můžete použít jak argument vyvíjet (), pokud chcete jen zkontrolovat, zda je nutné aktualizovat, nebo chcete-li být líný jako účastníka, který jsme nazvali dříve.
Řazení manažerů schématu
Často subsystémů, které tvoří aplikace spoléhají na další subsystémy správně fungovat. Pokud oba subsystémy poskytnout manažerům schématu, je často užitečné znát pořadí, ve kterém budou dovolávat se evolvers. To umožňuje rámec a je to klient, aby mohl vyvíjet ve shodě, a klienti mohou vědět, že rámec bude vyvinul před nebo po sobě.
Toho lze dosáhnout tím, že řídí jména manažera schéma utilit. Manažeři schématu jsou provozovány v pořadí určeném tříděním jejich jména.
& Nbsp; >>> manager1 = SchemaManager (minimum_generation = 0, generace = 0)
& Nbsp; >>> manager2 = SchemaManager (minimum_generation = 0, generace = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, name = "another.app")
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, name = 'another.app-rozšíření ")
Všimněte si, jak název prvního balíčku se používá k vytvoření jmenný prostor pro závislé balíčky. To není požadavek rámce, ale vhodný vzor pro toto použití.
Pojďme vyvíjet databáze za účelem stanovení těchto generací:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; >>> kořen [generations_key] ['another.app']
& Nbsp; 0
& Nbsp; >>> kořen [generations_key] ['another.app-rozšíření "]
& Nbsp; 0
Předpokládejme, že z nějakého důvodu každý z těchto subsystémů potřebuje přidat generaci, a že generace 1 "another.app-rozšíření" závisí na generaci 1 "another.app". Budeme muset poskytnout manažerům schématu pro každý tento záznam, že už běží, takže můžeme ověřit výsledek:
& Nbsp; >>> gsm.unregisterUtility (za předpokladu = ISchemaManager, name = "another.app")
& Nbsp; pravda
& Nbsp; >>> gsm.unregisterUtility (
& Nbsp; ... za předpokladu = ISchemaManager, name = 'another.app-rozšíření ")
& Nbsp; pravda
& Nbsp; >>> třída FoundationSchemaManager (objekt):
& Nbsp; ... nářadí (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generace = 1
& Nbsp; ...
& Nbsp; ... def vyvíjet (self, kontext, generace):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... uspořádání = root.get ("uspořádání", [])
& Nbsp; ... pokud generace == 1:
& Nbsp; ... ordering.append ("nadace 1 ')
& Nbsp; ... print "nadace generace 1 '
& Nbsp; ... jinak:
& Nbsp; ... zvýšit ValueError ("průšvih")
& Nbsp; ... kořen ['objednací'] = objednací # ping persistence
& Nbsp; ... transaction.commit ()
& Nbsp; >>> třída DependentSchemaManager (objekt):
& Nbsp; ... nářadí (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generace = 1
& Nbsp; ...
& Nbsp; ... def vyvíjet (self, kontext, generace):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... uspořádání = root.get ("uspořádání", [])
& Nbsp; ... pokud generace == 1:
& Nbsp; ... ordering.append ("v závislosti 1 ')
& Nbsp; ... print "závislý generace 1 '
& Nbsp; ... jinak:
& Nbsp; ... zvýšit ValueError ("průšvih")
& Nbsp; ... kořen ['objednací'] = objednací # ping persistence
& Nbsp; ... transaction.commit ()
& Nbsp; >>> manager1 = FoundationSchemaManager ()
& Nbsp; >>> manager2 = DependentSchemaManager ()
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, name = "another.app")
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, name = 'another.app-rozšíření ")
Vyvíjející databázi nyní bude vždy spustit "another.app" Evolver před "another.app-rozšíření" Evolver:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; nadace Generation 1
& Nbsp; v závislosti generace 1
& Nbsp; >>> kořen ['uspořádání']
& Nbsp; ['základ 1', 'závislá 1']
Instalace
Ve výše uvedeném příkladu jsme ručně inicializaci odpovědi. Neměli bychom to dělat ručně. Aplikace by měla být schopen to udělat automaticky.
IInstallableSchemaManager rozšiřuje ISchemaManager, poskytuje instalace způsob vykonání intial instalaci aplikace. To je lepší alternativou než registrace účastníků databáze otevřena.
Definujme nového manažera schéma, které zahrnuje instalaci:
& Nbsp; >>> gsm.unregisterUtility (za předpokladu = ISchemaManager, name = "some.app")
& Nbsp; pravda
& Nbsp; >>> od zope.generations.interfaces import IInstallableSchemaManager
& Nbsp; >>> třída MySchemaManager (objekt):
& Nbsp; ... nářadí (IInstallableSchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generace = 2
& Nbsp; ...
& Nbsp; ... def nainstalovat (self, kontext):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... kořen ['odpovědi'] = {'Hello': "Ahoj a jak to děláte,",
& Nbsp; ... "? Smyslu života": "42",
& Nbsp; ... "čtyři & Nbsp; ... transaction.commit ()
& Nbsp; ...
& Nbsp; ... def vyvíjet (self, kontext, generace):
& Nbsp; ... root = context.connection.root ()
& nbsp; ... odpovědi = root ['odpovědi']
& Nbsp; ... pokud generace == 1:
& Nbsp; ... na otázku, odpověď v answers.items ():
& Nbsp; ... odpovědi [test] = cgi.escape (odpověď)
& Nbsp; ... elif generace == 2:
& Nbsp; ... na otázku, odpověď v answers.items ():
& Nbsp; ... del odpovědi [test]
& Nbsp; ... odpovědi [cgi.escape (otázka)] = odpověď
& Nbsp; ... jinak:
& Nbsp; ... zvýšit ValueError ("průšvih")
& Nbsp; ... kořen ['odpovědi'] = odpovědi # ping trvalost
& Nbsp; ... transaction.commit ()
& Nbsp; >>> manager = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manažer, ISchemaManager, name = "some.app")
Teď, umožňuje otevřít nové databáze:
& Nbsp; >>> db.Close ()
& Nbsp; >>> db = DB ()
& Nbsp; >>> Conn = db.open ()
& Nbsp; >>> "odpovědi" v conn.root ()
& Nbsp; False
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; >>> conn.sync ()
& Nbsp; >>> root = conn.root ()
& Nbsp; >>> pprint (kořenové ['odpovědi'])
& Nbsp; {"Hello": "Ahoj a jak to děláte?",
& Nbsp; "smysl života?": "42",
& Nbsp; "čtyři & Nbsp; >>> kořen [generations_key] ['some.app']
& Nbsp; 2
Protokol ZODB transakce bere na vědomí, že naše instalační skript byl popraven
& Nbsp; >>> [. It.description pro něj v conn.db () storage.iterator ()] [- 2]
& Nbsp; u'some.app: spuštění instalace generace "
(Menší poznámka: to není poslední záznam, protože existují dvě nezavazuje: MySchemaManager provádí jeden, a evolveMinimumSubscriber provádí druhý MySchemaManager není opravdu nutné potvrzení.).

Co je nového v této verzi:.

  • Byla přidána podpora pro Python 3.3
  • Nahradil zastaralé použití zope.interface.implements s rovnocenným zope.interface.implementer dekoratér.
  • Ukončení podpory pro Python 2.4 a 2.5.

Co je nového ve verzi 3.7.1:

  • Odebráno buildout část, která byla použita při vývoji, ale dělá Nekompilujte na Windows.
  • Generace skripty přidání transakce poznámku.

Požadavky na :

  • Python

Ostatní software developer Zope Corporation and Contributors

zope.app.testing
zope.app.testing

14 Apr 15

zope.configuration
zope.configuration

14 Apr 15

z3c.layer.pagelet
z3c.layer.pagelet

15 Apr 15

refline.srccheck
refline.srccheck

14 Apr 15

Komentáře k zope.generations

Komentáře nebyl nalezen
Přidat komentář
Zapnout obrázky!