Existen muchos mecanismos de conexión a base de datos SQL desde Plone CMS, en este articulo se enfoca en la amplia usada librería SQLAlchemy y sus mecanismos de integración.
SQLAlchemy, es un toolkit de SQL en Python para hacer mapas de objetos relacionales (ORM - Object Relational Mapper) que le permite a los desarrolladores de aplicaciones incorporar toda la potencia e flexibilidad del estándar SQL.
Del ingles ZSQL Methods, los métodos ZSQL son un objeto similar a un método DTML de Zope o scripts de Python especializados para su uso con bases de datos relacionales. Son la forma más fácil de conectar RDBMS en Zope. Contiene comando SQL y DTML en combinación.
Existen varios productos disponibles para integrar SQLAlchemy con Plone como se describen a continuación:
- Alchemist, utiliza la librería SQLAlchemy, Zope 3 component architecture, y Zope 3 formlib / schema / widgets le permite el desarrollo rápido de aplicaciones orientadas a base de datos objetos con Zope 2, Zope 3, y Plone.
- collective.saconnect, es una panel de control Plone para configurar la conexión SQLAlchemy.
- collective.lead, este es otro paquete de integración transaccional SQLAlchemy/Zope2.
- z3c.saconfig, ofrece una simple pero flexible forma de configurar un ámbito de sesión de SQLAlchemy soportada usando la Zope component architecture.
En el producto elegido para esta labor es z3c.saconfig a continuación se describe su configuración:
- La configuración de la conexión se realiza en el fichero configure.zcml.
- Se usan la utilidad global y utilidad local.
- Pueden ser configuradas como conexiones globales - por una instancia de Zope.
- O locales para cada sitio Plone.
A continuación un ejemplo del archivo configure.zcml:
<include package="z3c.saconfig" file="meta.zcml"/>
<db:engine name="cliente1_registros"
url="postgresql://usuario:contrasena@127.0.0.1/db_cliente1_registros?charset=utf8" />
<db:session name="cliente1.registros" engine="cliente1_registros" />
A continuación un ejemplo del archivo config.py:
from sqlalchemy.ext.declarative import declarative_base
from z3c.saconfig import named_scoped_session
Base = declarative_base()
SCOPED_SESSION_NAME = 'cliente1.registros'
session = named_scoped_session(SCOPED_SESSION_NAME)
A continuación un ejemplo del archivo interfaces.py:
from zope import interface, schema
from cliente1.registros import MessageFactory as _
class IProject(interface.Interface):
"""Defines Project form interface.
"""
fullname = schema.TextLine(
title=_(u'Project name'),
required=True)
email = schema.TextLine(
title=_(u"Project e-mail"),
required=True)
type = schema.Choice(
title=_(u'Category'),
vocabulary=vocabulary.member_types,
default='profissional',
description=_(u'''Please select a project category.'''),
required=True)
status = schema.TextLine(
title=_(u'Project status'),
required=True)
created_date = schema.TextLine(
title=_(u'Project created date'),
required=True)
organization = schema.TextLine(
title=_(u'Organization'),
description=_(u'Please advise which organization '\
'you belong. eg company, university or entity.'),
required=False)
A continuación un ejemplo del archivo models.py:
import datetime
import sqlalchemy as sa
from cliente1.registros.config import Base
class Project(Base):
"""A project"""
implements(IProject)
__tablename__ = 'project'
id = Column(sa.Integer,nullable=False,index=True,primary_key=True)
fullname = Column(sa.String(64))
email = Column(sa.String(64), unique=True)
type = Column(sa.String(64))
status = Column(sa.String(64), default='pending')
created_date = Column(sa.DateTime, default=datetime.datetime.now())
organization = Column(sa.String(255))
El objetivo general de z3c.form y hacer que el desarrollo de formularios lo más simples posible, mientras que proporciona hooks para permitir la personalización de los formularios en cualquier nivel de acuerdo a las necesidades reales de los diferentes casos de uso.
Los principales componentes (módulos):
A continuación los elementos principales del procesamiento del formulario:
Para esto se usa la receta zc.buildout llamada collective.recipe.pgcreatedb el cual crea una base de datos Postgresql a través de SQLAlchemy, a continuación ejemplo de su configuración:
[buildout]
parts =
...
rdbs-requeriments
rdbs-createdb
...
# This recipe helps to install Postgresql pre-requeriments
# For options see http://pypi.python.org/pypi/plone.recipe.command
[rdbs-requeriments]
recipe = plone.recipe.command
command =
sudo aptitude install -y postgresql postgresql-server-dev-all libpq-dev phppgadmin
stop-on-error = false
update-command = ${rdbs-requeriments:command}
...
# This recipe helps to create a database Postgresql with SQLAlchemy
# For options see https://svn.plone.org/svn/collective/collective.recipe.pgcreatedb/trunk
[rdbs-createdb]
recipe = collective.recipe.pgcreatedb
default-template = template1
user = postgres
password = postgres
database = db_cliente1_registros
host = 127.0.0.1
create-tables = off
eggs = ${instance:eggs}
extra-paths = ${buildout:parts-directory}/
...
En la sección buildout llamada rdbs-requeriments instala el servidor postgresql con sus librerías de desarrollo y adicionalmente instala phppgadmin para la gestión remota del mismo.
En la sección buildout llamada rdbs-createdb crea crea una base de datos Postgresql a través de SQLAlchemy.
A continuación se demuestra un ejemplo del archivo import_steps.xml para la creación de las tablas:
- La creación de las tablas se lleva a cabo al disparar el perfil de importación del producto.
- El archivo import_steps.xml.
<?xml version="1.0"?>
<import-steps>
<import-step id="identificador-create_tables" version="20101020-11"
handler="cliente1.registros.setuphandlers.create_tables"
title="Create Base Tables">
<dependency step="toolset" />
</import-step>
</import-steps>
A continuación un ejemplo del archivo setuphandlers.py:
from z3c.saconfig import named_scoped_session
from cliente1.registros.config import Base
from cliente1.registros.config import SCOPED_SESSION_NAME
Session = named_scoped_session(SCOPED_SESSION_NAME)
class create_tables(context):
'''Called at profile import time to create necessary tables'''
if isNotOurProfile(context):
return
Base.metadata.create_all(bind=Session.bind)
Ver también
Artículos sobre Presentar información de una base de datos relacional y Utilizando formularios z3c.form en Plone.
El código fuente de este archivo esta hospedado en GitHub. Todos pueden actualizar y corregir errores en este documento con unos clic - sin necesidad de descargar.
Para mas información básica acerca de como actualizar este manual y referencia a sintaxis Sphinx, por favor consulte la guía Escribiendo y actualizando el manual.