Design OO, Design E-R, e o tal do ORM.

April 6, 2009

Vira e mexe aparece algum problema que pode ser um exercício interessante, um Kata para programador que eu gostaria de colocar aqui para ser analisado, discutido e implementado pelo pessoal que visita o blog. Além disso, tem algum tempo também que eu quero escrever sobre os conflitos entre o design Orientado a Objeto e o desenvolvimento de aplicações usando banco de dados relacionais, e sobre como as ferramentas que fazem ORM tentam, mas não conseguem resolver esse conflito de uma forma definitiva.

Como não estou com tempo para fazer tudo isso, vou fazer um mix e ver o que acontece. Resumidamente, vou explicar um pequeno problema que eu tenho envolvendo a implementação de um sistema usando o ORM do Django, e gostaria de saber se alguém vê uma solução correta e elegante.

Usando exemplos reais: estou trabalhando em um projeto que visa analisar registros médicos eletrônicos e identificar se certos casos registrados devem ser notificados ao CDC. Mais especificamente, o que eu quero é analisar o registro de vacinas que a pessoa recebeu e verificar se houve alguma reação adversa. Uma reação adversa pode ser identificada por algo comum como febre, ou algo mais complexo como uma hemorragia ou por um exame de laboratório mostrando uma variação em valores de seus componentes (Hemoglobina, Creatina, Sódio, Potássio, etc).

“Falando” OO, o que eu tenho é a classe AdverseEvent, da qual derivam FeverEvent, DiagnosticsEvent e LabResultEvent. Na hora de construir os relatórios, é necessário obter a lista dos eventos e obter também os atributos específicos de cada subclasse. Até aí OO funciona. E antes que the-one-who-can’t-be-named grite “Design Patterns”, eu vou falar que estamos lidando com a implementação de uma Factory: dada uma lista de chaves que identifique uma lista de AdverseEvents, a Factory instancia o objeto adequado a partir da id fornecida.

O “problema”: esses objetos ficam em um banco de dados, e como mapear isso para um banco de dados relacional e fazer uma factory que construa o objeto adequado com uma única consulta?

Vamos ao código. A primeira solução seria uma implementação que tenta ser puramente OO. O código abaixo é parte de um típico módulo de definição dos seus modelos quando usando Django.

 

class AdverseEventManager(models.Manager):

    def by_id(self, key):
        for klass in [FeverEvent, DiagnosticsEvent, LabResultEvent]
            try:
                obj = klass.objects.get(id=key)
                return obj
            except: pass
        return None

class AdverseEvent(models.Model):
    # Managers
    objects = models.ModelManager()
    manager = AdverseEventManager()

    # Atributos que realmente são de interesse e vão para o BD.
    patient = models.ForeignKey(Demog)
    immunization = models.ForeignKey(Immunization)
    matching_rule_explain = models.CharField(max_length=200)
    category = models.CharField(max_length=20, choices=ADVERSE_EVENT_CATEGORIES)
    created_on = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)



# Classes filhas. NO BD, são mapeadas para tabelas que contém os campos 
# específicos da classe, e referencia a tabela da classe-pai
class FeverEvent(AdverseEvent):
    temperature = models.FloatField('Temperature')
    encounter = models.ForeignKey(Enc)

class DiagnosticsEvent(AdverseEvent):
    encounter = models.ForeignKey(Enc)
    icd9 = models.ForeignKey(Icd9)


class LabResultEvent(AdverseEvent):
    lab_result = models.ForeignKey(Lx)

 

 

O Factory method é by_id. Para os que não conhecem Django, ModelManager.get() faz a consulta no banco de dados e retorna um único objeto da classe que o contém, ou a exceção DoesNotExist se não existir objetos com os parâmetros indicados. Como a chave pertence a classe-pai, podemos ter certeza que não há haverá objetos das classes filhos com o mesmo id. Isso permite que encontremos o objeto desejado. O problema com essa solução é que o número de consultas é proporcional ao número de sub-classes

O segundo esquema é “menos OO”. Para desespero de alguns puristas, nós podemos criar um dicionário no módulo que mapeia as sub classes possíveis e a factory faz sempre duas consultas para obter o objeto apropriado.

 

ADVERSE_EVENT_CLASSES = {'fever':FeverEvent,
                         'diagnostics':DiagnosticsEvent,
                         'lab_result': LabResultEvent
                         }

class AdverseEventManager(models.Manager):  
    def by_id(self, key):
        try:
           ev = AdverseEvent.objects.get(id=key)
           return ADVERSE_EVENT_CLASSES[ev.event_type].objects.get(id=key)
        except:
            return None

class AdverseEvent(models.Model):
    # Managers
    objects = models.ModelManager()
    manager = AdverseEventManager()

    # Atributos que realmente são de interesse e vão para o BD.
    patient = models.ForeignKey(Demog)
    immunization = models.ForeignKey(Immunization)
    matching_rule_explain = models.CharField(max_length=200)
    category = models.CharField(max_length=20, choices=ADVERSE_EVENT_CATEGORIES)
    created_on = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)

    # Adicionamos esse campo para identificar para saber qual é a subclasse 
    event_type = models.CharField(max_length=20, choices=tuple(ADVERSE_EVENT_CLASSES.items()))

 

 

Enfim, só estou expondo as duas soluções que eu conheço para lidar com algo trivial. Se alguém tiver alguma idéia diferente, por favor deixe registrado nos comentários.

Com relação a crítica ao ORM: parte da minha bronca são essas incongruências que existem, o ORM não conseguindo fazer uma boa ponte entre o modelo OO e o modelo E-R. É por detalhes assim que estamos começando a ver uma série de projetos de banco de dados não-relacionais, do qual espero falar mais adiante.

Outra coisa interessante: se você perceber, um banco de dados XML não teria esse problema, entretanto parece que ninguém nunca pensou em implementar o BDB-XML como backend para uma datastore.

tags: , , ,
posted in Design, Teoria by Raphael Lullis

Follow comments via the RSS Feed | Leave a comment | Trackback URL

  • mgalves

    Prefiro a segunda opção, por ser bem mais razoavel em termos de busca. Django inclusive oferece uma solução própria para a segunda query do segundo modelo apresentado:

    “If you have a Place that is also a Restaurant, you can get from the Place object to the Restaurant object by using the lower-case version of the model name:

    p = Place.objects.filter(name="Bob's Cafe")

    If Bob’s Cafe is a Restaurant object, this will give the child class:

      p.restaurant
      <Restaurant: ...>
    

    However, if p in the above example was not a Restaurant (it had been created directly as a Place object or was the parent of some other class), referring to p.restaurant would raise a Restaurant.DoesNotExist exception.”

  • Leonardo Garcia

    Dois comentários Raphael:

    1) Não sei exatamente o que você vai dizer sobre bancos de dados não-relacionais, mas pelo menos até onde eu conheço, bancos de dados orientados a objeto costumam ter um desempenho sofrível. Talvez isto tenha mudado nos últimos anos.

    2) Não sou especialista no assunto, mas se não me engano alguns bancos de dados comerciais possuem suporte para bases de dados em XML. Eu arriscaria dizer que o DB2 da IBM e o SQLServer da Microsoft possuem este suporte. Mas não tenho certeza.

  • http://bpfurtado.livejournal.com/ Bruno

    Raphael,

    Eu li até agora até o ponto:

    “Falando” OO, o que eu tenho é a classe AdverseEvent, da qual derivam FeverEvent, DiagnosticsEvent e LabResultEvent. Na hora de construir os relatórios, é necessário obter a lista dos eventos e obter também os atributos específicos de cada subclasse. Até aí OO funciona.
    E posso dizer que identifiquei uma falácia muito comum quando se fala de OO. Desenho de Software Orientado a Objetos não trata da organização/classificação de dados, não foi concebido para isto, e sim para aumentar o reuso de código, OO foi concebida pensando no comportamento do software e demaneira alguma em diferentes métodos de organizar seus dados. Para isto o struct de C já era suficiente…

    Um dos 4 pilares para o uso de desenho OO é a Classificação, mas classificação do comportamento presente entre diferentes classes de componentes, e não classificação do ponto de vista de seus dados, suas propriedades, seu estado.

    OO é comportamento, e não dados, os dados são apenas a infraestrutura, um meio para o correto funcionamento dos métodos. OO tem como objetivo aumentar o reuso e melhorar a manutenção dos métodos e não dos dados/estrutura de seu código.

    Mas vou ler o resto e comentar mais.

    [ ]‘s!!

  • http://bpfurtado.livejournal.com/ Bruno
    2) Não sou especialista no assunto, mas se não me engano alguns bancos de dados comerciais possuem suporte para bases de dados em XML. Eu arriscaria dizer que o DB2 da IBM e o SQLServer da Microsoft possuem este suporte. Mas não tenho certeza.

    O Oracle com certeza possui operações de alto nível para persistir e buscar estruturas no formato XML, mas eu nunca tive o desprazer de utilizar, hehe.

  • http://bpfurtado.livejournal.com/ Bruno
    E antes que the-one-who-can’t-be-named grite “Design Patterns”

    Caros, eu realmente espero não ser este cara… it would make no sense ;-)

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael,

    Assim… suas dúvidas são bem específicas a solução ORM provida pelo Django… e isto não pode ser base para critiar outras soluções ORM, ou mesmo a sua proposta geral.

    O Hibernate por exemplo lida muito bem com a questão do polimorfismo e como recuperar instâncias de Classes que participam de uma determinada hierarquia. Ele disponibiliza pelo menos 3 “estratégias” para tanto, cada uma com o seus prós e contras.

  • http://raphael.lullis.net Raphael Lullis

    Quanto ao primeiro texto. O que você tá falando não é novidade pra ninguém. Poderíamos ficar batendo boca pra ver quem sabe arrotar mais jargões e platitudes como “Desenho de Software Orientado a Objetos não trata da organização/classificação de dados, não foi concebido para isto, e sim para aumentar o reuso de código”, mas se for pra isso, paramos aqui.

    O propósito do post não foi definir do que trata o Design OO, ou achar defeito no Design OO. É a de achar uma forma eficiente de tapar as “leaky abstractions” que aparecem quando se usa um banco de dados relacional (E-R) para fazer a persistência de uma aplicação que manipula e “pensa” em objetos.

    Quanto ao segundo, estou curioso: Qual é mágica que o Hibernate faz para evitar esse problema?

  • http://bpfurtado.livejournal.com/ Bruno

    Raphael

    Quanto ao primeiro texto. O que você tá falando não é novidade pra ninguém.
    Sua afirmação de que “… até ai OO resolve.” contradiz isto claramente.

    Poderíamos ficar batendo boca pra ver quem sabe arrotar mais jargões e platitudes como “Desenho de Software Orientado a Objetos não trata da organização/classificação de dados, não foi concebido para isto, e sim para aumentar o reuso de código”, mas se for pra isso, paramos aqui.

    Jargões? Raphael, aprenda, isto é um fato e não uma opinião pessoal minha, por favor, entenda isto. (neste ponto realmente começa a parecer que isto ainda é novidade para você)

    O propósito do post não foi definir do que trata o Design OO, ou achar defeito no Design OO.

    Nem por isto eu poderia deixar de comentar o erro conceitual.

    É a de achar uma forma eficiente de tapar as “leaky abstractions” que aparecem quando se usa um banco de dados relacional (E-R) para fazer a persistência de uma aplicação que manipula e “pensa” em objetos.

    Mas que “leaky abstractions”? Voce se refere a Herança?

    Quanto ao segundo, estou curioso: Qual é mágica que o Hibernate faz para evitar esse problema?

    A mágica por trás dos panos eu não sei, mas a maneira de como configurar isto pode ser vista em:

  • http://raphael.lullis.net Raphael Lullis

    Bruno, devagar. Respira fundo. Tá lendo o que não foi escrito. ;)

    Eu não falei que o que você escreveu é jargão. Falei que poderíamos ficar trocando jargões. Diferente. O que você escreveu, eu disse que é uma platitude.

    Além do mais, eu falei “Até aí OO funciona“, diferente de “resolve“. “Funciona”, no caso, é no sentido de servir como uma abstração lógica, capaz de fazer um mapeamento direto entre o comportamento do objetos “reais” e os objetos “lógicos”.

    O que não “funciona”, a “leaky abstraction” que eu tô falando, é a de usar um banco de dados relacional para fazer a persistência desses objetos. O que eu tô vendo é justamente que não tem ORM que vá te conseguir ao mesmo tempo:

    • prover uma interface para obter todos os objetos que fazem parte de uma mesma hierarquia
    • obter todos os atributos desses objetos em uma única query.
    • Manter o modelo OO “funcionando”.
    • Manter o modelo E-R “funcionando”.

    Dá uma olhada nas estratégias do Hibernate: a primeira (table per class hierachy) faz uma única consulta e obtém todos os objetos. “Funciona” no OO, mas quebra o E-R (todos os campos têm que ser NULLABLE). A segunda (one table per subclass) é parecida com o que o ORM do Django faz e não consegue fazer uma única busca que retorne objetos especializados. As outras também.

    Enfim, o ponto do post é que a “mágica por trás dos panos” não fica transparente. E não é por falha de um ou outro ORM. É algo generalizado e inerente a qualquer ORM.

  • http://bpfurtado.livejournal.com/ Bruno
    Eu não falei que o que você escreveu é jargão. Falei que poderíamos ficar trocando jargões. Diferente. O que eu realmente falei sobre o que você escreveu é que é uma platitude.

    Cliché ou não, você errou forte no conceito. E é estranho você dizer que é trivialmente óbvio: “falar que OO diz respeito a comportamento” quando no seu texto você se refere a OO como uma maneira de organizar dados hierarquicamente. Sem rodeios Raphael, você escreveu isto preto no branco, é só dar page up.

    Além do mais, eu falei “Até aí OO funciona“, diferente de “resolve“. “Funciona”, no caso, é no sentido de servir como uma abstração lógica, capaz de fazer um mapeamento direto entre o comportamento do objetos “reais” e os objetos “lógicos”.

    Outro erro comum, OO não deve mapear objetos “reais”, mas realmente acho que isto é outra discussão.

    O que não “funciona”, a “leaky abstraction” que eu tô falando, é a de usar um banco de dados relacional para fazer a persistência desses objetos.

    Realmente, eu não classificaria isto como uma “leaky abstraction”, posso estar errado mas não me soa como um termo apropriado neste contexto.

    O que eu tô vendo é justamente que não tem ORM que vá te conseguir ao mesmo tempo:

    O que você viu foi o Django tentando fazer ORM, e não ORM independente de implementação. Seus argumentos falam especificamente do Django, correto? Quantas outras soluções para ORM você testou? Podem até ter sido várias, mas não foram citadas no seu texto.

    prover uma interface para obter todos os objetos que fazem parte de uma mesma hierarquia obter todos os atributos desses objetos em uma única query. Manter o modelo OO “funcionando”. Manter o modelo E-R “funcionando”.

    Até onde eu sei, o Hibernate é usado com sucesso para tanto. É uma ferramenta complexa, pois a tarefa não é menos; possui seus pontos de atenção e limitações, mas no geral é muito madura, muito bem suportada, muito documentada e base para uma série de outras ferramentas. No geral ele cumpre esta missão muito bem. E ainda posso dizer que a maior parte das críticas cliché feitas a ele vem de pessoas que não se deram ao trabalho de estudar a API e que gostariam que tudo funcionasse com um next >> next >> finish; Ai eu digo, a ferramenta é gratuita, quer criticar? Perfeito, mas que seja com conhecimento de causa.

    Dá uma olhada nas estratégias do Hibernate: a primeira (table per class hierachy) faz uma única consulta e obtém todos os objetos. “Funciona” no OO, mas quebra o E-R (todos os campos têm que ser NULLABLE).

    Tudo deve ser pesado em um determinado contexto, garanto que em vários esta troca compensa, veja, não existe mágica no desenho de software, você insere uma complexidade em uma região do seu desenho para ter flexibilidade, agilidade em outra, a questão única é pesar se isto é vantajoso para as suas operações sobre o modelo.

    A segunda (one table per subclass) é parecida com o que o ORM do Django faz e não consegue fazer uma única busca que retorne objetos especializados. As outras também.

    Raphael, como??? As 2 páginas que eu lhe passei falam em vários pontos sobre como configurar o Hibernate de forma que as buscas sejam “polimórficas”.

    Enfim, o ponto do post é que a “mágica por trás dos panos” não fica transparente. E não é por falha de um ou outro ORM. É algo generalizado e inerente a qualquer OR

    Não vi embasamento no seu post para falar de nada que não fosse a solução ORM disponibilizado pelo Django.

  • http://raphael.lullis.net Raphael Lullis

    Bruno, Bruno…

    É uma leaky abstraction justamente por obrigar a pessoa que está fazendo a implementação do programa a “configurar o Hibernate para que as buscas sejam polimórficas”. Se a abstração fosse perfeita, o ORM jamais ia requerer esse tipo de conhecimento pela pessoa responsável pela implementação.

    Mas a abstração não é perfeita, pô. O mecanismo que o Django te dá para lidar com isso envolve os detalhes que eu e o Miguel escrevemos. O Hibernate requer que você mexa com o “plumbing”, configuração. Não tem como fugir: não tem ORM que vá fazer um RDBMS funcionar como uma object datastore eficiente, sem precisar de intervenção do cara que tá implementando o programa.

    E de novo, você veio com platitudes (saco, tenho que parar de usar essa palavra que eu acho que só existe em inglês) ao falar que “tudo deve ser pesado em um contexto”. Qual é o contexto que que te obriga a usar um RDBMS como datastore da tua aplicação e, consequentemente, te força a usar um ORM?

    Considere a alternativa: já parou pra pensar que se a datastore escolhida fosse o BDB-XML, você não precisaria do Hibernate, ou qualquer outro ORM?

    Ps.: posso pedir, por favor, pra você parar de responder com quotes? Eu sei que já cometi esse crime antes, muitas vezes. Mas responder com mil blockquotes “espalha” a conversa pra mil pontos diferentes e, pior, não ajuda a construir uma discussão coerente.

  • http://rnaufal.livejournal.com Rafael Naufal

    @Raphael

    Claro que tudo em desenvolvimento de software depende sim de um contexto, que envolve tanto requisitos funcionais quanto os não-funcionais que vc deve implementar (performance, escalabilidade, tempo de resposta, etc..)

    É por isso que o Hibernate te fornece a flexibilidade de configurar 3 estratégias para recuperar instâncias das entidades do seu modelo.

    Pelo visto, o Django nem permite que vc recupere polimorficamente instâncias de suas classes do RDBMS (o teu exemplo provou isso). Isto sim para mim já é uma leaky abstraction, pois em se tratando da aplicação dos conceitos do paradigma OO, eu gostaria de recuperar “instâncias das minhas subclasses”..

    O Hibernate recupera de uma forma transparente instâncias das subclasses se a superclasse é abstrata. E fazendo amplo uso das estratégias (table per class hierarchy, table per subclass, table per concrete class) de mapeamento do mundo OO para o mundo E-R que ele oferece.

    Cara, como eu sempre digo, é um tradeoff. Em certas situações, complexidades são adicionadas em alguns pontos do código, para se ganhar flexibilidade e facilidade de manutenção no futuro. E isso vai de projeto para projeto. É vc como desenvolvedor quem deve pesar e avaliar isto.

  • Miguel Galves

    @Rafael e @Bruno, o ponto todo da discussão não era se era impossível ou não criar esta camada, nem de discutir as vantagens do Hibernate em relação ao Django. É óbvio que com um pouco de programação e uma bela camada de código, qualquer um de nós seria capaz de criar uma lib que persistisse uma estrutura de objetos, em BD, arquivo properties, XML, YAML.

    O ponto levantado é o fato deste mapeamento não ser transparente no sentido de sacrificar algo. No caso, o escolhido para o sacrifício é o modelo ER (no caso de table per hierarchy que faria qualquer teórico de BD tremer). E no caso da escolha recair sobre o table per subclass, tem que se fazer várias queries para se obter o resultado. A filosofia do Hibernate é de fazer de tudo para que a gente esqueça que o BD exista (oferecendo até uma linguagem de query própria orientada a objetos). A leaky abstraction está no fato de que, alguma hora ou outra, seremos obrigados a lembrar que SIM, a base existe (seja na hora de configurar o dito cujo, seja na hora de tentar entender certas coisas que acontecem por baixo dos panos). O Django optou por um modelo ORM mais sóbrio, oferecendo algumas atalhos para o processo de CRUD, mas sem pretensões de abstrair completamente a existência da base de dados, fazendo com que certas coisas precisem de algumas linhas a mais de código. Vai do gosto de cada um.

    Mas que em ambos os casos temos uma leaky abstraction, isso não resta dúvidas. Basta ler o artigo original do Joel para entender.

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael,

    OO permite a criação de abstrações com uma finalidade completamente distinta da organização, persistência e recuperação de dados, é claro que ela é inadequada em diversos aspectos fora do contexto para a qual foi concebida. Nem por isto acho que ela esteja ‘vazando’, hehe.

    Agora tomando emprestada a definição da Wikipédia para “Leaky abstraction”:

    This article may contain original research or unverified claims. Please improve the article by adding references. See the talk page for details. (March 2009) A leaky abstraction is a notion applied to implementations of an abstraction. This notion indicates that specific implementation details manifest themselves in a counter-productive way, thus interfering with the abstraction. The implementation details are said to “leak through” and interfere with the simplifying assumptions supposedly enabled by the abstraction. Within the software industry, leaky abstractions are a common source of software bugs.
    Eu não vejo a implementação específica de Java dos conceitos de OO, interferindo nos mecanismos de como criar ferramentas do tipo ORM. OO ou o OO de Java não lhe obriga a criar arquivos de configuração para um framework X realizar a operação Y. OO permite o uso de abstrações ótimas para alcançar os ganhos que eu já mencionei (só neste blog, diversas vezes).

    Me diga, como seria possível uma abstração ‘perfeita’ (nas suas palavras) para Organizar dados e e reuso/manutenção de código? Acho que isto está mais para a pedra filosofal do desenho de software atualmente, não? Meu ponto é, você está colocando um trator em um autódromo de F1 e uma Ferrari em uma plantação de milho, e criticando ambos por não funcionarem bem, faz sentido isto?

    Ai você mesmo diz que a abstração não é perfeita, “pô”, ai eu digo: toda ferramenta tem o seu contexto, “pô!”.

    O que você chama de ‘intervenção’, eu chamo de simples configuração para o uso de uma determinada ferramenta, vai tentar usar um osciloscópio sem ter o treinamento adequado antes, não tem mágica meu amigo, com ferramentas de software é a mesma coisa! O desenho de software não é nada banal, o uso de seu ferramental tão pouco, requer estudo. Transformar as abstrações de OO para um SGBD não é nada fácil, as boas ferramentas para tanto, são sofisticas e muitas vezes por justamente permitir ao desenvolvedor diversas abordagens para ‘sabores’ diferentes de problemas.

    Se você acha que uma abstração é ‘leaky’ porque requer ‘plumbing’ para se transformar em outra completamente díspar, então eu acho que você precisa rever seus conceitos cuidadosamente.

    E sobre usar o BD orientado a XML, isto não resolve em nada nossos problemas, correto? XML, OO, XML… OO… tem missões totalmente diferentes não? XML não foi feito para vencer os mesmos desafios que um BD enfrenta, correto?

  • http://raphael.lullis.net Raphael Lullis

    Bruno.

    Cansa, viu?

    O ponto chave que você está esquecendo é que banco de dados não precisam ser relacionais. Não é “colocar um trator em um autódromo de F1 e uma Ferrari em uma plantação de milho, e criticar ambos por não funcionarem bem”, é mostrar que, pra correr no asfalto, a Ferrari não precisa do trator na plantação de milho.

    O lance da leaky abstraction, você está errado, ou simplesmente se recusando a entender o que o Miguel falou. Não estamos falando dos detalhes da implementação do Java interferindo na implementação do ORM. Estamos falando que os detalhes do RDBMS estão interferindo na implementação geral do teu programa.

    O ORM, meu caro, só se faz necessário num mundo onde o banco de dados relacional se faz necessário. E um banco de dados relacional não é necessário em muitos casos. Esse é o ponto.

    Usar “BD orientado a XML” pode resolver nossos problemas, sim. E, melhor ainda, pode ser uma abstração sem “vazamento”. XML permite a representação de dados muito mais livre de restrições; uma linguagem como XQuery fornece poder de buscar elementos eficientemente. Um banco de dados como o BDB-XML é ACID. E tudo isso pode ser usado para implementar uma aplicacão dispensando o uso de um ORM.

    Ps.: Obrigado por parar com os blockquotes. :) O pedido da vez vai ser o de não distorcer os fatos a lógica para tentar provar seu ponto. Chamar BDB-XML de “BD orientado a XML” e depois dizer “que XML não foi feito para vencer os mesmos desafios que um BD enfrenta” é desonestidade intelectual. A parte “XML” é só a casca, mas o produto continua sendo um BD.

  • Leonardo Garcia

    Raphael e Bruno,

    Sem querer entrar no meio das suas discussões particulares mas já entrando :P desta vez eu concordo com o Raphael. E não discordo do Bruno! Só acho que o Bruno está falando sobre uma coisa diferente do que o Raphael queria discutir (pelo menos desta vez).

    Raphael,

    Tenho que concordar com você desta vez porque definitivamente existe uma “leaky abstraction” entre a modelagem OO e o desenho de um BD relacional. E este problema não está no Django ou no Hibernate: está na essência que definem as abstrações que estão sendo utilizadas. Aliás, sempre me senti muito incomodado por isso, desde muito tempo. E, como você bem disse, não vejo uma solução razoável para isso a não ser não usar BDs relacionais. Por outro lado, não usar BDs relacionais até pouco tempo atrás era quase proibitivo para algo que precisasse do mínimo de escala. Ou seja, respondendo à pergunta original do seu post, não vejo nenhuma solução mais elegante do que as que você propôs. Qualquer uma delas resolve o problema com uma implementação que “cole” os modelos teóricos.

    Bruno,

    Concordo com você de que OO e BDs relacionais não casam porque tem propósitos diferentes. Mas para mim simplesmente dizer que isso é assim e que portanto precisamos de um código para ligar as duas coisas não resolve o problema como um todo. Quero dizer, resolve o problema de implementação imediato, sem dúvida nenhuma, mas não resolve o incômodo que eu sinto todas as vezes que eu tenho que escrever uma solução que ligue OO e um BD relacional. Eu acho que é deste incômodo que o Raphael está falando. E acho que pode existir uma solução para ele: ela só não está disponível facilmente no momento. Mas é justamente deste incômodo que eu acho que soluções melhores do que as disponíveis atualmente (e.g. Django, Hibernate, etc.) podem surgir. Soluções que resolvam o problema teórico e não apenas que colem dois modelos que não foram pensados com o mesmo propósito.

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael,

    Se o ponto chave era dizer que Bancos não Relacionais são a melhor opção para persistir Objetos, então eu realmente acho você se perdeu com os argumentos, exemplos, ao colocar casos específicos de Django, etc.

    Se você queria, no texto inicial, dizer que um Banco Relacional nem sempre se faz necessário (e o google já diz isto há muito tempo) então eu além de concordar contigo, acho que novamente, seu artigo não foi corretamente direcionado para esta conclusão. Muito pelo contrário, só no final ele cita brevemente que esta poderia ser uma alternativa, e se limita a isto, meu caro.

    Agora, a maneira XML de representar dados pode ser mais direta com relação a objetos de um Modelo OO, mas engana-se gravemente quem pensa que isto sai de graça, a ausência da característica relacional traz consequências que podem ser graves em muitos contextos, ou nós nunca precisamos do aspecto relacional para os nossos dados, estávamos enganados o tempo todo? I hardly think so.

    Não existe mágica, se seus dados realmente não se relacionam muito entre si, realmente um banco de dados relacional seja um preço muito caro, se o paradigma big table lhe atende suficientemente bem, well, cada caso é um caso, é isto Raphael, que parece que você não entendeu ainda. Não existe uma ferramenta perfeita para todos os problemas, e é seu papel, como desenvolvedor de software, conhecer a ferramenta certa para cada problema, saber pesar o impacto de cada ferramenta escolhida versus o seu benefício.

    As ferramentas atuais de ORM, podem demandar realmente mais plumbing do que o que seria ‘agradável’ (e mesmo nesta área elas já evoluíram muito), mas eu te digo uma coisa, para sistemas de médio porte, eu não fico sem elas, depois delas minha tolerância para a quantidade de trabalho braçal para escrever SQL caiu muito, e não por acaso, mas porque um esforço compensa e muito o outro (always the trade-off).

    Seu último ‘PS’ eu vou desconsiderar todo, com exceção do A parte “XML” é só a casca, mas o produto continua sendo um BD, francamente, se assim fosse, então o Berkley DB original já seria o suficiente, não? XML é mais do que a casca, é como seus dados estão organizados, e para um DB isto e levemente relevante, não?

    Side story: Agora só um detalhe cômico sobre o material de propaganda do ‘Oracle Berkeley DB XML’: it runs in process with the application with no need for human administration. Qual o público que engole uma besteira desta guela a baixo?

  • http://raphael.lullis.net Raphael Lullis

    O BDB original só não é suficiente por faltar a ele uma linguagem de query dos registros. Há bibliotecas para fazer a manipulação dos registros disponíveis para qualquer plataforma, mas falta a parte de query. É aí que entra a “casca XML”.

    Posso apostar contigo que a parte de armazenamento e recuperação dos dados, bem como toda a parte de ACID-compliance são idênticas nos dois BDBs. A única diferença é que o BDB-XML oferece o XML como uma interface para o usuário e a aplicação, e com isso ganha-se o benefício de poder fazer uso de XQuery.

    Ah, sim. O BDB roda como uma biblioteca do teu binário – da mesma forma que o SQLite – não existe servidor, logo a afirmação não é tão cômica assim.

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael, please, a parte cômica é dizer que só porque ele funciona in-process LOGO ele não precisa de “human administration”.

    Eu tenho certeza que o armazenamento utilizado pelo ‘Oracle Berkeley DB XML’ é baseado no Berkeley DB ‘classico’, porque é praticamente tudo que ele é, uma engine de armazenamento a lá ‘hashtable’, e jogar fora este aspecto seria jogar fora praticamente ele todo.

    O errado é dizer “XML é só casca” como quem diz: “a estrutura da minha informação pouco importa sobre a maneira através da qual eu irei armazená-la”. No caso específico do Oracle BDB isto até pode se aplicar, mas pelo motivo citado acima.

  • http://bpfurtado.livejournal.com/ Bruno

    @Miguel,

    Eu não concorco com a afirmação de que o modelo adotado pelo Django é mais ‘sóbrio’, ele é sim menos ‘pretencioso’ de acordo com a sua descrição.

  • http://bpfurtado.livejournal.com/ Bruno

    @Leonardo,

    Não tem mágica, no modelo OO as informações que um BD relacional demanda não estão presentes, então das duas uma, ou você provê estas informações para a sua solução de ORM, ou a sua solução de ORM assume uma série de decisões (e.g. valores para seus parâmetros de configuração), hoje o Hibernate adota ambas as estratégias, assim como outras ferramentas.

    Você vê a possibilidade de outra estratégia para resolver este problema?

  • Miguel Galves

    @Bruno, não precisa concordar. Esta é a minha opinião.

    Extrapolando um pouco o tópico, e correndo o risco de iniciar mais uma infindável discussão, a qual eu não pretendo contribuir, devo dizer que uma coisa nisso tudo eu realmente acho engraçado: você advoga o uso da melhor ferramenta para cada situação. Mas eu não me lembro de ler aqui você defendendo algo que não fosse da pilha JEE. E inclusive nesta discussão, você insiste em reduzir tudo à uma compração entre django e hibernate, mesmo quando ja falamos que esse não era o ponto inicial.

    Dai eu pergunto: a melhor ferramenta para qualquer situação sempre será uma ferramenta Java, com o melhor OO, o melhor ORM, o melhor container de aplicações, o melhor framework IOC, e por aí vai?

  • http://raphael.lullis.net Raphael Lullis

    Alguns posts acima você estava querendo me dar lição sobre OO, dizendo que o importante do OO é comportamento e não o arranjo das estruturas de dados. Ao criticar o BDB-XML, você faz parecer que a forma que teus dados são armazenados importa para quem faz uma aplicação com modelo OO.

    Não vou mais responder aqui. O ponto do post ficou razoavelmente claro para os outros, mas você parece mais preocupado em defender os seus métodos. E cai em contradições: ora defende a necessidade do E-R, ora diz que é aceitável o relaxamento do E-R em favor do modelo OO (o uso do ORM), mas não aceita a idéia de que o E-R pode ser inteiramente eliminado da equação.

    Já vamos começar a andar em círculos e eu prometi a mim mesmo que não vou mais perder meu tempo com isso.

  • http://bpfurtado.livejournal.com/ Bruno

    @miguel, cara, ou você começa uma discussão ou não começa, se você já diz que não vai comentar futuramente, ou seja, só vai jogar a bomba e sair correndo, eu é que não vou perder o meu tempo em te responder.

    Suas afirmações no último parágrafo, como dizer que eu só recomendo a pilha JEE não fazem o MENOR sentido…

  • Leonardo Garcia

    Bruno,

    Você me perguntou se eu vejo a possibilidade de outra estratégia para resolver este problema? Bom, minha resposta é não. Mas isso não quer dizer que eu não possa me sentir incomodado em resolvê-lo desta forma. Mas, na falta de algo que eu ache melhor e que me dê a escala de que eu preciso, continuo com estas soluções descritas aqui mesmo.

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael,

    Não critiquei o BDB-XML, nem o BDB, mas sim e apenas o texto de marketing da Oracle. E isto JAMAIS faria parecer que eu quis dizer que isto QUALQUER influência em um modelo OO, de onde você tira estas idéias??

    E se esta era a contradição que você espera encontrar nos meus argumentos, bem, procure outra então.

    Eu não defendi a necessidade de E-R, cara, onde isto? Disse que cada problema tem o seu contexto e se você precisa que eu lhe diga que ER é necessário em vários contexto, bem… eu sei que você não precisa que eu lhe diga isto.

    Eu disse qualquer coisa sobre o relaxamento do modelo ER em favor do OO??? Please, page ups e leia novamente, eu disse que tanto o ER quanto o OO naturalmente só tem informações que dizem respeito a si mesmos, e se você quer migrar dados de um para o outro, é natural que a necessidade de um certo plumbing, ou assumir certas decisões (bom, já falei sobre isto né, page up and read).

    O E/R totalmente eliminado da equação? Com exceção da estratégia onde o framework/API assumem toda informaçao que falta no modelo OO (que eu descrevi acima), qual seria esta estratégia? Eu aceito a idéia, me mostre como, ou quem faz isto, simples.

    Você notou uma coisa? Você não conseguiu dizer uma só afirmação correta a respeito da minha argumentação, nem uma.

  • http://raphael.lullis.net Raphael Lullis

    Dude, onde está a “sua argumentação”? De tudo que você falou até agora, nada está fazendo contraponto às idéias do texto.

    Os pontos que você parece concordar comigo, você simplesmente fala que meu texto foi curto na conclusão, ou que o Google já falou antes.

    Nos outros pontos, você ou está buscando pêlo em ovo, ou falando que “existe trade-off para justificar o uso do E-R” (e consequentemente, o uso do ORM).

    Eu estou expondo um caso onde um RDBMS é usado apenas como datastore. No meu caso, não há necessidade de manter integridade nem de relações nem de dados na camada de persistência, Espero que isso seja suficiente para te mostrar que não há “design E-R”, nem “requisitos de dados”. A conclusão: se não há “modelo E-R” que tem que ser enforced, então podemos pensar em outras estratégias para o banco de dados; preferencialmente uma que dispense o uso do ORM, seja ele qual for.

    Você está querendo “rebater” falando de projetos onde há requisitos que justificam o modelo E-R. Totalmente fora do conjunto de problemas que eu falei. Como é que você quer que eu “argumente” contra algo que nem faz parte do meu ponto original?

  • http://bpfurtado.livejournal.com Bruno

    @Raphael, dude,

    De todo o seu post, apenas a frase “É por detalhes assim que estamos começando a ver uma série de projetos de banco de dados não-relacionais, do qual espero falar mais adiante.” remete ao tema do uso de bases de dados não relacionais (3% se você considerar o número de palavras uma boa métrica).

    O restante diz respeito a estratégias para persistir objetos em bases relacionais, tornando impossível chegar à sua última conclusão com base no post inicial. O resto ficou para “mais adiante…”.

    Não me admira então, ninguém saber qual é o ponto central desta discussão.

    Só para concluir, em determinado ponto eu falei a respeito de se pesar os prós e contras em relação ao uso de ORMs, em contrapartida à codificação braçal de código SQL, e não para justificar o uso de uma base Relacional. Codificação manual de SQL, que é muito do que está em jogo quando se opta por utilizar uma solução para ORM. E ORM é justamente do que se trata o seu post (tirando 3%…).

  • http://raphael.lullis.net Raphael Lullis

    Péra aí!

    O único que não sabe qual é o ponto central és tu. O Léo só faltou fazer um desenho esquematizando o meu “raciossímio” pra você. O Miguel até cansou de tentar fazer você entender que a discussão não era sobre Django e Hibernate, nem sobre ORM. Nem o Naufal falou algo nessa linha. Não venha falar “ninguém sabe qual é o ponto da discussão”. Você é a exceção, não a regra.

    Discordo da tua contagem de palavras como métrica, mas isso é assunto pra outra hora. Ainda que fosse uma métrica válida, você pode adicionar aí a menção ao BDB-XML como uma alternativa de datastore que não é RDBMS e não faria uso do ORM.

    E, cáspita, eu falo por analogias e exemplos. O problema foi pra exemplificar o cenário (muito comum) onde usa-se RDBMS como dumb datastore, o que leva a incongruências entre mundo OO e mundo E-R, incongruências essas tentam ser eliminadas pela adoção do ORM, mas que mesmo assim não são resolvidas. A crítica, se é que há alguma, é ao uso indiscriminado de RDBMS, não do ORM.

    Pra encerrar: em nenhum ponto eu disse algo na linha “ORM sucks, melhor escrever SQL à mão”, disse? Você querer trazer isso pra discussão é sem sentido.

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael,

    Se você não admite nem mesmo que usar 3% do seu texto para o que seria o tema principal não é uma boa tática… well, sobre isto eu não tenho mais nada a dizer.

    Eu também não disse que você prefere escrever código SQL manualmente, como você mesmo disse “Cansa, viu?”.

    Abordando então o tema proposto:

    Agora algo que eu lembrei nestes dias, na época em que o AppEngine saiu, e o BigTable atingiu as massas, eu comecei a acompanhar a lista do Google sobre a nova plataforma de aplicações, era impressionante o número de posts de desenvolvedores querendo ‘enxertar’ o aspecto relacional dos dados na estrutura BigTable.

    Se eles simplesmente não tentaram entender a nova proposta ou se a natureza de seus dados é ‘relacional’ mesmo, eu não sei, mas com certeza tinha muita gente perdida ali que nada estudou antes de ‘meter os dedinhos no teclado’.

    De qualquer forma é essencial entender porque o Google investiu e investe tanto paradigma BigTable, quais problemas o Google resolveu com esta maneira de representar seus dados? Redundancia (distribuição) e Performance me vem em mente, o Gmail me vem em mente, o cache das páginas web (da engine de busca) me vem em mente, todos dados ‘não relacionais’, ou apenas relacionais no sentido de cada um deles ter uma lista de hashcodes para outras entidades, e lembrando que a próxima busca só seria feita em outra requisição… hmmm…. Depois de refletir nisto e provavelmente em mais aspectos/exemplos de uso, ai podemos entender melhor se o BigTable também atenderia as necessidades de nossas aplicações.

    Mas no meu mundo ideal eu teria tempo para testar o Google Apps e a tal BigTable, seria bem interessante brincar com isto. Btw, eu criei a conta logo no lançamento ‘da coisa’ e me deram um belo chá de cadeira até liberarem meu acesso.

  • bruno da silva

    como naum tenho experiencia nem conhecimento em django soh posso dizer o seguinte:

    o post devia ter um titulo especifico e naum generico : tipo probemas o ORM do django

    a primeira implementacao exemplo eh realmente muito ruim naum pq eh mais OO mais sim pq no q o exemplo me leva a crer o ORM do django eh ruim.

    a segunda eh realmente ruim do ponto de vista de OO em um pequeno projeto naum teria muitos problemas mais um projeto grande pq vc perdeu todo o ganho de produtividade de OO.

    se o interesse eh fazer um post generico o post deveria ter um exemplo com java/hibernate , grails e ruby in rails tb.

  • Miguel Galves

    Bruno da Silva, qual seria a tua solução? A boa solução?

  • bruno da silva

    acho q naum tem solucao no momento pra django … veja o link

    http://peterbraden.co.uk/article/django-inheritance

    mais com java /hibernate vc naum tem esse problema.

  • http://raphael.lullis.net Raphael Lullis

    Bruno,

    Nos comentários, nós discutimos sobre o Hibernate. Pelo que eu vi, o Hibernate permite obter as sub-classes, sim. Mas perceba que o problema de que estamos falando ainda existe: o ORM pode até fornecer uma ponte entre o mundo OO e o mundo E-R, mas isso não fica completamente isolado da pessoa responsável em implementar uma aplicação.

    Falando na linguagem que teu xará gosta: um ORM ajuda a “manipular dados” como se fossem objetos, mas não consegue esconder detalhes da implementação. O fato de termos um banco de dados relacional obriga, no fim das contas, a que tenhamos que saber quais os detalhes de como funciona a persistência dos objetos.

    Esse problema é independente de ORM. Faz parte da arquitetura de todo e qualquer sistema que se utilizar de um RDBMS para fazer persistência de dados.

    Ps.: Não quero ser mais chato do que o de costume, mas posso pedir um pouco mais de capricho nos comentários? Pontuação, acentos, o uso correto de “mas/mais” ajudam muito pra que a gente possa compreender melhor o que você tá querendo dizer.

  • http://bpfurtado.livejournal.com/ Bruno

    @Bruno Silva,

    Concordo contigo que o ORM do Django deve ser bem inferior ao Hibernate, mas a questão toda é que o Raphael alega que a discussão não é sobre ORMs mas sim sobre a ‘leak abstraction’ (palavras dele) que seriam os Banco de Dados Relacionais… Eu acho que em primeiro lugar ele escreveu muito mal, uma vez que o texto dele fala só de ORM/Django technical details) e outra que a idéia dele é absurda, os bancos relacionais não são ‘leak abstractions’ pelo simples fato deles não conseguirem entender as instancias de um modelo OO sem nenhuma configuração extra, eles não foram feitos para isto, conceitualmente. Mais uma vez cito aqui a comparação entre usar um trator no lugar de uma Ferrari e vice-versa.

  • http://raphael.lullis.net Raphael Lullis

    Bruno,

    Quando você tem a cara-dura pra comentar que eu escrevo mal, é pra ofender mesmo ou é só falta de tato?

  • bruno da silva

    ignorancia de persistencia = IP

    se o problema eh IP o hibernate faz muito bem com POJOs

    mas deixando claro IP se faz na camada de dominio (domain)

    e vc vai ter sim uma camada de repositorio (infrastructure) que vai ser persistence aware.

    como diz o motto do django ” The Web framework for perfectionists with deadlines ” naum acho q naum eh o objetivo do django trazer IP.

    alguns links sobre IP :

    http://colinjack.blogspot.com/2007/03/persistence-ignorance-and-associations.html

    http://en.wikipedia.org/wiki/POJO

    http://codebetter.com/blogs/gregyoung/archive/2008/07/24/impedance-mismatch-reframing.aspx

    coloquei alguns exemplos de .net pq em java IP jah tah bem batido e o mundo .net agora tah comecando a descobri-la

    quanto ao meu portugues escrito … digamos q escrevo portugues dinamico… portugues phyton.

  • http://bpfurtado.livejournal.com/ Bruno

    Correção: Não quero dizer que o Raphael escreve mal, acho que sim, se a intenção do artigo foi a que ele disse nos ultimos replies, então este artigo em particular poderia ser muito melhor direcionado.

  • Miguel Galves

    Bruno,

    a leaky abstraction não é a base de dados relacional! Nunca foi dito isso. Mesmo porque o modelo relacional é uma das poucas coisas na computação que tem uma teoria matemática sólida. A leaky abstraction é a COLA feita para se amarrar OO com ER.

    Ficou claro isso???

  • http://raphael.lullis.net Raphael Lullis

    Bruno, claro que poderia ser melhor direcionado. Mas eu mesmo dei a dica:

    Além disso, tem algum tempo também que eu quero escrever sobre os conflitos entre o design Orientado a Objeto e o desenvolvimento de aplicações usando banco de dados relacionais, e sobre como as ferramentas que fazem ORM tentam, mas não conseguem resolver esse conflito de uma forma definitiva. Como não estou com tempo para fazer tudo isso, vou fazer um mix e ver o que acontece.
  • bruno da silva

    eu acho q no caso do django naum eh um leaky abstration e sim um lack of abstration.

    eu pessoalmente acho L.A. eh uma coisa muito subjetiva e aposto q no nas API de bases relacionais temos varios L.A. assim como em ORMs

    eh bem complicado distinguir falta de conhecimento sobre uma tecnologia e uma L.A.

    acho q esse assunto eh bem polemico.

    eh merece um post diferente …

  • http://bpfurtado.livejournal.com/ Bruno

    @Miguel,

    Não, não ficou claro, qual é a abstração cujos detalhes de implementação estão “leaking“?

    Uma das respostas do Raphael:

    O lance da leaky abstraction, você está errado, ou simplesmente se recusando a entender o que o Miguel falou. Não estamos falando dos detalhes da implementação do Java interferindo na implementação do ORM. Estamos falando que os detalhes do RDBMS estão interferindo na implementação geral do teu programa.

    A “COLA” para amarrar OO e ER é o ORM, e sim, ele PRECISA ter informação para preencher a lacuna entre as configurações entre as diferentes abstrações. Este é justamente seu papel e responsabilidade, e não sua falha. Concluindo com suas palavras: “ficou claro???”

    @Raphael, você usou uma frase, que representa quase um centésimo do seu texto para o que você queria que fosse o tema central do seu post, eu não tenho dúvidas, seu texto foi muito mal direcionado, muito. Não fosse esta frase, você sequer teria tocado no seu ‘tema central’, não te ajuda ficar ressaltando isto.

  • Miguel Galves

    Não quer entender, então não entenda. Quer continuar discutindo se o texto estava mal escrito, continue.

  • http://bpfurtado.livejournal.com/ Bruno

    @Miguel,

    “Não quer entender, então não entenda.” eu poderia lhe dizer a mesmíssima coisa.

    Quanto ao direcionamento do texto, eu já tentei parar de falar a respeito, e não sou só eu quem ficou trazendo isto de volta.

    Também entrei na discussão proposta pelo Raphael no dia 15/Abr: “Abordando então o tema proposto: ….”. Mas ai, surpresa, quando eu finalmente entrei no tema sugerido, ninguém respondeu.

  • http://raphael.lullis.net Raphael Lullis

    Bruno. Desculpe por ter cometido um erro tão grave. Mil perdões.

    Meu erro foi ter imaginado que todos os leitores (ao menos os leitores que participam da discussão) são espertos o suficiente para entender que um RDBMS é muito mais do que “a ferramenta que você precisa ter para fazer persistência e busca de dados”.

    Foi muito idiota da minha parte supor que os leitores (ao menos os leitores que participam da discussão) fossem capazes de entender a generalidade do problema que estou falando usando apenas um pequeno exemplo.

    Perdoe-me por tal atrocidade que eu escrevi. Realmente, tal peça não é digna de um leitor como você. Estou publicamente me retratando. Quero aproveitar e deixar claro que, graças a você (e não ao meu parágrafo introdutório), todos os outros leitores vão poder perceber que o meu texto está carente de informação e não apresenta certos princípios para fazer uma argumentação mais sólida. É um texto simples, escrito em pouco minutos para tentar mostrar um caso onde as consideradas best-practices não funcionam de forma satisfatória, mas sei que você não merece nada menos do que um artigo que passe por peer-review e seja aprovado para publicação em uma instituição de respeito.

    Eu estou trabalhando na continuação, para tentar corrigir a minha trapalhada. Se quiser, posso colocar um rascunho disponível para a sua análise prévia. Não quero cometer o mesmo erro de ter um texto mal-direcionado novamente.

    Mais uma vez peço desculpas, Raphael Lullis

  • http://bpfurtado.livejournal.com/ Bruno

    @Raphael, whatever…

    Seu erro foi teimar que a idéia central do texto era discutir alternativas à bases de dados relacionais, se você não tivesse teimado em algo claramente errado, então nós não teríamos perdido tanto tempo com o que eu acredito não merecer sequer discussão, já que é óbvio que o seu post tratava principalmente (-3%) da critica de estratégias de ORM.

    Se você dissesse, “oks, eu deveria ter enfatizado melhor, mas whatever, o que voce pensa disto?” ai eu teria ficado 100% ‘na minha’.

    Seu sarcasmo exacerbado pouco me importa, acredite.

    Faça uma pesquisa no log4dev e pergunte se o ao ler este seu post o entendimento do tema central é o que você espera:

    Pergunta para a Pesquisa: Ao ler o post do dia DD/MM, você acredita que o tema central proposto para discussão é:

    • O ORM do Django e suas limitações;
    • ORMs quaisquer e suas limitações;
    • Estratégias de mapeamento de Objetos em Bases Relacionais;
    • Estratégias de mapeamento de Objetos em Bases Relacionais e como o Django trata desta questão;
    • Alternativas ao uso de Bases de Dados relacionais;
    • Como realizar buscas com resultados polimórficos no ORM do Django;
    • Como realizar buscas com resultados polimórficos em ORMs quaisquer;
    Eu tenho certeza de que você ficará surpreso.

  • http://raphael.lullis.net Raphael Lullis

    Bruno, way to miss the point. Perceba que a tua pesquisa não inclui nenhuma alternativa “O texto não é uma discussão, apenas um exemplo prático de problemas que surgem ao querer fazer a ponte entre aplicações que tem modelo OO e E-R”.

    A conversa aqui vai virar pissing contest. Podemos parar com isso?

  • Leonardo Garcia

    Massa! Outros meios significa que vai ter briga na saída da aula?! :P

blog comments powered by Disqus

Switch to our mobile site

 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org