zope.generations

Software screenshot:
zope.generations
Rincian Software:
Versi: 4.0.0 Alpha 1
Tanggal Upload: 15 Apr 15
Lisensi: Gratis
Popularitas: 2

Rating: nan/5 (Total Votes: 0)

zope.generations menyediakan cara memperbarui objek dalam database ketika perubahan aplikasi skema & nbsp;. Sebuah skema aplikasi pada dasarnya struktur data, struktur kelas dalam kasus ZODB atau deskripsi tabel dalam kasus database relasional.
Detil Dokumentasi
Generasi adalah cara memperbarui objek dalam database ketika perubahan aplikasi skema. Skema aplikasi pada dasarnya struktur data, struktur kelas dalam kasus ZODB atau deskripsi tabel dalam kasus database relasional.
Bila Anda mengubah struktur data aplikasi Anda, misalnya, Anda mengubah makna semantik dari medan yang ada di kelas, Anda akan memiliki masalah dengan database yang dibuat sebelum perubahan Anda. Untuk diskusi yang lebih menyeluruh dan solusi yang mungkin, lihat http://wiki.zope.org/zope3/DatabaseGenerations
Kami akan menggunakan arsitektur komponen, dan kita akan membutuhkan database dan sambungan:
& Nbsp; >>> import cgi
& Nbsp; >>> dari pprint impor pprint
& Nbsp; >>> dari zope.interface alat impor
& Nbsp; >>> dari ZODB.tests.util impor DB
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> root = conn.root ()
Bayangkan bahwa aplikasi kita adalah oracle: Anda bisa mengajarkannya untuk bereaksi terhadap frase. Mari kita tetap sederhana dan menyimpan data dalam dict:
& Nbsp; >>> akar ['jawaban'] = {'Hello': '? Hi & bagaimana Anda melakukannya',
& Nbsp; ... '? Arti hidup': '42',
& Nbsp; ... 'empat & Nbsp; >>> transaksi impor
& Nbsp; >>> transaction.Commit ()
Pengaturan awal
Berikut adalah beberapa kode generasi-spesifik. Kami akan membuat dan mendaftarkan SchemaManager a. SchemaManagers bertanggung jawab untuk update sebenarnya dari database. Ini akan hanya bodoh. Intinya di sini adalah untuk membuat generasi modul menyadari bahwa aplikasi kita mendukung generasi.
Pelaksanaan default SchemaManager tidak cocok untuk tes ini karena menggunakan modul Python untuk mengelola generasi. Untuk saat ini, itu akan baik-baik saja, karena kita tidak ingin melakukan apa-apa dulu.
& Nbsp; >>> dari zope.generations.interfaces impor ISchemaManager
& Nbsp; >>> dari zope.generations.generations impor SchemaManager
& Nbsp; >>> impor zope.component
& Nbsp; >>> dummy_manager = SchemaManager (minimum_generation = 0, generasi = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... dummy_manager, ISchemaManager, nama = 'some.app')
'Some.app' adalah sebuah identifikasi unik. Anda harus menggunakan URI atau nama bertitik paket Anda.
Ketika Anda mulai Zope dan database dibuka, sebuah IDatabaseOpenedWithRoot event dikirim. Zope register evolveMinimumSubscriber secara default sebagai handler untuk event ini. Mari kita mensimulasikan ini:
& Nbsp; >>> kelas DatabaseOpenedEventStub (object):
& Nbsp; ... def __init __ (self, database):
& Nbsp; ... self.database = Database
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> dari zope.generations.generations impor evolveMinimumSubscriber
& Nbsp; >>> evolveMinimumSubscriber (event)
Konsekuensi dari tindakan ini adalah bahwa sekarang database berisi fakta bahwa jumlah skema kami saat ini adalah 0. Ketika kita memperbarui skema, Zope3 akan memiliki gagasan tentang apa titik awal adalah. Di sini, lihat?
& Nbsp; >>> dari zope.generations.generations impor generations_key
& Nbsp; >>> akar [generations_key] ['some.app']
& Nbsp; 0
Dalam kehidupan nyata Anda tidak harus repot-repot dengan kunci ini secara langsung, tetapi Anda harus menyadari bahwa itu ada.
Upgrade skenario
Kembali ke cerita. Beberapa waktu berlalu dan salah satu klien kami hacked karena kita lupa untuk melarikan diri HTML karakter khusus! Horor! Kita harus memperbaiki masalah ini secepatnya tanpa kehilangan data apapun. Kami memutuskan untuk menggunakan generasi untuk mengesankan teman-teman kami.
Mari kita memperbarui manajer skema (drop lama dan menginstal kustom baru satu):
& Nbsp; >>> dari zope.component impor globalregistry
& Nbsp; >>> gsm = globalregistry.getGlobalSiteManager ()
& Nbsp; >>> gsm.unregisterUtility (disediakan = ISchemaManager, nama = 'some.app')
& Nbsp; Benar
& Nbsp; >>> kelas MySchemaManager (object):
& Nbsp; ... alat (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generasi = 2
& Nbsp; ...
& Nbsp; ... def berkembang (self, konteks, generasi):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... jawaban = akar ['jawaban']
& Nbsp; ... jika generasi == 1:
& Nbsp; ... untuk pertanyaan, jawaban dalam answers.items ():
& Nbsp; ... jawaban [pertanyaan] = cgi.escape (jawaban)
& Nbsp; ... generasi Elif == 2:
& Nbsp; ... untuk pertanyaan, jawaban dalam answers.items ():
& Nbsp; ... del jawaban [pertanyaan]
& Nbsp; ... jawaban [cgi.escape (pertanyaan)] = jawaban
& Nbsp; ... lain:
& Nbsp; ... meningkatkan ValueError ("Nyebelin")
& Nbsp; ... akar ['jawaban'] = jawaban # ping ketekunan
& Nbsp; ... transaction.Commit ()
& Nbsp; >>> manager = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manajer, ISchemaManager, nama = 'some.app')
Kami telah menetapkan minimum_generation ke 1. Itu berarti bahwa aplikasi kita akan menolak untuk berjalan dengan database lebih tua dari generasi 1. Atribut generasi diatur ke 2, yang berarti bahwa generasi terbaru yang SchemaManager ini tahu tentang adalah 2.
berkembang () adalah pekerja keras di sini. Tugasnya adalah untuk mendapatkan database dari generasi ke generasi 1. Ia mendapat konteks yang memiliki atribut 'koneksi', yang merupakan koneksi ke ZODB. Anda dapat menggunakannya untuk mengubah benda-benda seperti dalam contoh ini.
Dalam generasi implementasi tertentu 1 lolos jawaban (misalnya, kritis, karena mereka bisa dimasuki oleh siapa saja!), Generasi 2 lolos pertanyaan (misalnya, kurang penting, karena ini dapat dimasukkan oleh yang berwenang personell saja).
Bahkan, Anda tidak benar-benar membutuhkan implementasi kustom dari ISchemaManager. Salah tersedia, kami telah menggunakannya untuk boneka sebelumnya. Menggunakan modul Python untuk organisasi fungsi Evolver. Lihat docstring untuk informasi lebih lanjut.
Dalam kehidupan nyata Anda akan memiliki lebih banyak struktur obyek yang kompleks dari yang di sini. Untuk membuat hidup Anda lebih mudah, ada dua fungsi yang sangat berguna yang tersedia di zope.generations.utility: findObjectsMatching () dan findObjectsProviding (). Mereka akan menggali melalui wadah rekursif untuk membantu Anda mencari benda tua yang ingin Anda memperbarui, dengan antarmuka atau beberapa kriteria lainnya. Mereka mudah untuk memahami, memeriksa docstrings mereka.
Generasi beraksi
Jadi, klien marah kita download kode terbaru kami dan restart Zope. Acara ini otomatis dikirimkan lagi:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
Shazam! Klien senang lagi!
& Nbsp; >>> pprint (root ['jawaban'])
& Nbsp; {'Hello': 'Hai & bagaimana Anda lakukan? ",
& Nbsp; "Arti hidup? ':' 42 ',
& Nbsp; 'empat Karena evolveMinimumSubscriber sangat malas, hanya update database cukup sehingga aplikasi Anda dapat menggunakannya (untuk minimum_generation, yaitu). Memang, penanda menunjukkan bahwa generasi database telah bertemu dengan 1:
& Nbsp; >>> akar [generations_key] ['some.app']
& Nbsp; 1
Kita melihat bahwa generasi bekerja, jadi kami memutuskan untuk mengambil langkah berikutnya dan berkembang ke generasi 2. Mari kita lihat bagaimana hal ini dapat dilakukan secara manual:
& Nbsp; >>> dari zope.generations.generations impor berevolusi
& Nbsp; >>> berkembang (db)
& Nbsp; >>> pprint (root ['jawaban'])
& Nbsp; {'Hello': 'Hai & bagaimana Anda lakukan? ",
& Nbsp; "Arti hidup? ':' 42 ',
& Nbsp; 'empat & Nbsp; >>> akar [generations_key] ['some.app']
& Nbsp; 2
Perilaku default upgrade berevolusi ke generasi terbaru yang disediakan oleh SchemaManager. Anda dapat menggunakan argumen bagaimana berevolusi () ketika Anda ingin hanya untuk memeriksa apakah Anda perlu memperbarui atau jika Anda ingin menjadi malas seperti pelanggan yang telah kita disebut sebelumnya.
Pemesanan manajer skema
Sering subsistem digunakan untuk menulis aplikasi bergantung pada subsistem lainnya untuk beroperasi dengan baik. Jika kedua subsistem memberikan manajer skema, sering membantu untuk mengetahui urutan evolvers akan dipanggil. Hal ini memungkinkan kerangka dan itu klien untuk dapat berkembang dalam konser, dan klien dapat mengetahui bahwa kerangka akan berevolusi sebelum atau setelah itu sendiri.
Hal ini dapat dicapai dengan mengendalikan nama utilitas manajer skema. Manajer skema dijalankan dalam urutan ditentukan oleh menyortir nama mereka.
& Nbsp; >>> manager1 = SchemaManager (minimum_generation = 0, generasi = 0)
& Nbsp; >>> manager2 = SchemaManager (minimum_generation = 0, generasi = 0)
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, nama = 'another.app')
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, nama = 'another.app-ekstensi')
Perhatikan bagaimana nama paket pertama digunakan untuk membuat namespace paket tergantung. Ini bukan persyaratan kerangka kerja, tapi pola yang nyaman untuk penggunaan ini.
Mari kita berevolusi database untuk membangun generasi ini:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; >>> akar [generations_key] ['another.app']
& Nbsp; 0
& Nbsp; >>> akar [generations_key] ['another.app-ekstensi']
& Nbsp; 0
Mari kita berasumsi bahwa untuk beberapa alasan masing-masing subsistem ini perlu untuk menambah satu generasi, dan bahwa generasi 1 dari 'another.app-ekstensi' tergantung pada generasi 1 dari 'another.app'. Kita harus memberikan manajer skema untuk setiap rekor yang mereka telah berjalan sehingga kita bisa memverifikasi hasilnya:
& Nbsp; >>> gsm.unregisterUtility (disediakan = ISchemaManager, nama = 'another.app')
& Nbsp; Benar
& Nbsp; >>> gsm.unregisterUtility (
& Nbsp; ... disediakan = ISchemaManager, nama = 'another.app-ekstensi')
& Nbsp; Benar
& Nbsp; >>> kelas FoundationSchemaManager (object):
& Nbsp; ... alat (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generasi = 1
& Nbsp; ...
& Nbsp; ... def berkembang (self, konteks, generasi):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... pemesanan = root.get ('memesan', [])
& Nbsp; ... jika generasi == 1:
& Nbsp; ... ordering.append ('pondasi 1')
& Nbsp; ... print 'pondasi generasi 1'
& Nbsp; ... lain:
& Nbsp; ... meningkatkan ValueError ("Nyebelin")
& Nbsp; ... akar ['memesan'] = memesan # ping ketekunan
& Nbsp; ... transaction.Commit ()
& Nbsp; >>> kelas DependentSchemaManager (object):
& Nbsp; ... alat (ISchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generasi = 1
& Nbsp; ...
& Nbsp; ... def berkembang (self, konteks, generasi):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... pemesanan = root.get ('memesan', [])
& Nbsp; ... jika generasi == 1:
& Nbsp; ... ordering.append ('tergantung 1')
& Nbsp; ... print 'generasi tergantung 1'
& Nbsp; ... lain:
& Nbsp; ... meningkatkan ValueError ("Nyebelin")
& Nbsp; ... akar ['memesan'] = memesan # ping ketekunan
& Nbsp; ... transaction.Commit ()
& Nbsp; >>> manager1 = FoundationSchemaManager ()
& Nbsp; >>> manager2 = DependentSchemaManager ()
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager1, ISchemaManager, nama = 'another.app')
& Nbsp; >>> zope.component.provideUtility (
& Nbsp; ... manager2, ISchemaManager, nama = 'another.app-ekstensi')
Berkembang database sekarang akan selalu menjalankan 'another.app' Evolver sebelum 'another.app-ekstensi' Evolver:
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; dasar generasi 1
& Nbsp; generasi tergantung 1
& Nbsp; >>> akar ['memesan']
& Nbsp; ['dasar 1', 'tergantung 1']
Instalasi
Dalam contoh di atas, kita secara manual diinisialisasi jawaban. Kita tidak harus melakukannya secara manual. Aplikasi ini harus dapat melakukannya secara otomatis.
IInstallableSchemaManager meluas ISchemaManager, menyediakan instalasi metode untuk melakukan instalasi Secara dini dari sebuah aplikasi. Ini adalah alternatif yang lebih baik daripada mendaftarkan pelanggan database dibuka.
Mari kita mendefinisikan manajer skema baru yang meliputi instalasi:
& Nbsp; >>> gsm.unregisterUtility (disediakan = ISchemaManager, nama = 'some.app')
& Nbsp; Benar
& Nbsp; >>> dari zope.generations.interfaces impor IInstallableSchemaManager
& Nbsp; >>> kelas MySchemaManager (object):
& Nbsp; ... alat (IInstallableSchemaManager)
& Nbsp; ...
& Nbsp; ... minimum_generation = 1
& Nbsp; ... generasi = 2
& Nbsp; ...
& Nbsp; ... def install (self, konteks):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... akar ['jawaban'] = {'Hello': '? Hi & bagaimana Anda melakukannya',
& Nbsp; ... '? Arti hidup': '42',
& Nbsp; ... 'empat & Nbsp; ... transaction.Commit ()
& Nbsp; ...
& Nbsp; ... def berkembang (self, konteks, generasi):
& Nbsp; ... root = context.connection.root ()
& Nbsp; ... jawaban = akar ['jawaban']
& Nbsp; ... jika generasi == 1:
& Nbsp; ... untuk pertanyaan, jawaban dalam answers.items ():
& Nbsp; ... jawaban [pertanyaan] = cgi.escape (jawaban)
& Nbsp; ... generasi Elif == 2:
& Nbsp; ... untuk pertanyaan, jawaban dalam answers.items ():
& Nbsp; ... del jawaban [pertanyaan]
& Nbsp; ... jawaban [cgi.escape (pertanyaan)] = jawaban
& Nbsp; ... lain:
& Nbsp; ... meningkatkan ValueError ("Nyebelin")
& Nbsp; ... akar ['jawaban'] = jawaban # ping ketekunan
& Nbsp; ... transaction.Commit ()
& Nbsp; >>> manager = MySchemaManager ()
& Nbsp; >>> zope.component.provideUtility (manajer, ISchemaManager, nama = 'some.app')
Sekarang, mari kita buka database baru:
& Nbsp; >>> db.close ()
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> 'jawaban' di conn.root ()
& Nbsp; Salah
& Nbsp; >>> event = DatabaseOpenedEventStub (db)
& Nbsp; >>> evolveMinimumSubscriber (event)
& Nbsp; >>> conn.sync ()
& Nbsp; >>> root = conn.root ()
& Nbsp; >>> pprint (root ['jawaban'])
& Nbsp; {'Hello': 'Hai & bagaimana Anda lakukan? ",
& Nbsp; "Arti hidup? ':' 42 ',
& Nbsp; 'empat & Nbsp; >>> akar [generations_key] ['some.app']
& Nbsp; 2
Log transaksi ZODB mencatat bahwa menginstal script kami dieksekusi
& Nbsp; >>> [. It.description untuk itu dalam conn.db storage.iterator () ()] [- 2]
& Nbsp; u'some.app: berjalan menginstal generasi '
(Catatan kecil: itu bukan catatan terakhir karena ada dua komit: MySchemaManager melakukan satu, dan evolveMinimumSubscriber melakukan yang kedua MySchemaManager tidak benar-benar perlu untuk melakukan..)

Apa yang baru dalam rilis ini:.

  • Ditambahkan dukungan untuk Python 3.3
  • Diganti usang zope.interface.implements penggunaan dengan setara zope.interface.implementer dekorator.
  • Turun dukungan untuk Python 2,4 dan 2,5.

Apa yang baru dalam versi 3.7.1:

  • Dihapus bagian buildout yang digunakan selama pengembangan tapi tidak tidak mengkompilasi pada Windows.
  • script Generation menambahkan catatan transaksi.

Persyaratan :

  • Python

Perangkat lunak lain dari pengembang Zope Corporation and Contributors

Komentar untuk zope.generations

Komentar tidak ditemukan
Tambahkan komentar
Aktifkan gambar!