Code

tiforadacaixa

Exemplos de uso SqlAlchemy

Exemplos de uso SqlAlchemy 

Lembrando que ja temos no blog um tutorial completo de uso do SqlAlchemy

A distribuição SQLAlchemy inclui uma variedade de exemplos de código que ilustram um conjunto selecionado de padrƵes, alguns tĆ­picos e outros nĆ£o. Todos sĆ£o executĆ”veis ​​e podem ser encontrados no /examplesdiretório da distribuição. DescriƧƵes e código fonte de todos podem ser encontrados aqui.
Exemplos adicionais de SQLAlchemy, com contribuição de alguns usuĆ”rios, estĆ£o disponĆ­veis no wiki em http://www.sqlalchemy.org/trac/wiki/UsageRecipes .

Mapeando Receitas 


Lista de adjacĆŖncias 

Um exemplo de uma estrutura de dicionÔrio de dicionÔrios mapeada usando um modelo de lista de adjacência.
Ex .:
node = TreeNode('rootnode')
node.append('node1')
node.append('node3')
session.add(node)
session.commit()

dump_tree(node)
Listagem de arquivos:

AssociaƧƵes 

Exemplos que ilustram o uso do padrão "objeto de associação", em que uma classe intermediÔria medeia o relacionamento entre duas classes que estão associadas em um padrão de muitos para muitos.
Listagem de arquivos:

  • proxied_association.py - O mesmo exemplo que basic_association, adicionando o uso de sqlalchemy.ext.associationproxypara fazer referĆŖncias explĆ­citas a OrderItemopcional.

  • basic_association.py - Ilustre um relacionamento muitos para muitos entre um "Pedido" e uma coleção de objetos "Item", associando um preƧo de compra a cada um deles por meio de um objeto de associação chamado "OrderItem"

  • dict_of_sets_with_default.py - Um exemplo avanƧado de proxy de associação que ilustra o aninhamento de proxies de associação para produzir coleƧƵes Python de vĆ”rios nĆ­veis, neste caso, um dicionĆ”rio com chaves de seqüência de caracteres e conjuntos de nĆŗmeros inteiros como valores, que ocultam as classes mapeadas subjacentes.

GrĆ”ficos direcionados 

Um exemplo de persistĆŖncia para uma estrutura de grĆ”fico direcionado. O grĆ”fico Ć© armazenado como uma coleção de arestas, cada uma referenciando um nó "inferior" e um "superior" em uma tabela de nós. A persistĆŖncia bĆ”sica e a consulta de vizinhos inferiores e superiores sĆ£o ilustradas:
n2 = Node(2)
n5 = Node(5)
n2.add_neighbor(n5)
print n2.higher_neighbors()
Listagem de arquivos:

RelaƧƵes dinĆ¢micas como dicionĆ”rios 

Ilustra como colocar uma fachada semelhante a um dicionÔrio em cima de uma relação "dinâmica", para que as operações do dicionÔrio (assumindo simples teclas de seqüência de caracteres) possam operar em uma grande coleção sem carregar a coleção completa de uma só vez.
Listagem de arquivos:

AssociaƧƵes genĆ©ricas 

Ilustra vÔrios métodos de associação de vÔrios tipos de pais a um objeto filho específico.
Todos os exemplos usam a extensĆ£o declarativa junto com mixins declarativos. Cada uma apresenta o caso de uso idĆŖntico no final - duas classes CustomerSupplier, ambas subclassificando o HasAddressesmixin, o que garante que a classe pai seja fornecida com uma addressescoleção que contenha Addressobjetos.
Os scripts discriminator_on_association.py e generic_fk.py sĆ£o versƵes modernizadas de receitas apresentadas na postagem de blog de 2007 Polymorphic Associations with SQLAlchemy .
Listagem de arquivos:

  • table_per_association.py - ilustra um mixin que fornece uma associação genĆ©rica por meio de tabelas de associação geradas individualmente para cada classe pai. Os próprios objetos associados sĆ£o mantidos em uma Ćŗnica tabela compartilhada entre todos os pais.

  • table_per_related.py - ilustra uma associação genĆ©rica que persiste objetos de associação em tabelas individuais, cada uma gerada para persistir esses objetos em nome de uma classe pai especĆ­fica.

  • discriminator_on_association.py - Ilustra um mixin que fornece uma associação genĆ©rica usando uma Ćŗnica tabela de destino e uma Ćŗnica tabela de associação, referida por todas as tabelas pai. A tabela de associação contĆ©m uma coluna "discriminador" que determina que tipo de objeto pai se associa a cada linha especĆ­fica na tabela de associação.

  • generic_fk.py - Ilustra a chamada ā€œchave estrangeira genĆ©ricaā€, de maneira semelhante Ć  de estruturas populares como Django, ROR etc. Essa abordagem ignora as prĆ”ticas de integridade referencial padrĆ£o, pois a coluna ā€œchave estrangeiraā€ nĆ£o Ć© realmente restrito a se referir a qualquer tabela especĆ­fica; em vez disso, a lógica no aplicativo Ć© usada para determinar qual tabela Ć© referenciada.

ColeƧƵes grandes 

Exemplo de coleção grande.
Ilustra as opƧƵes a serem usadas relationship()quando a lista de objetos relacionados Ć© muito grande, incluindo:
  • Relacionamentos ā€œdinĆ¢micosā€ que consultam fatias de dados acessadas
  • como usar o ON DELETE CASCADE em conjunto com passive_deletes=Truepara melhorar significativamente o desempenho da exclusĆ£o de coleção relacionada.
Listagem de arquivos:

Caminhos materializados 

Ilustra o padrão de "caminhos materializados" para dados hierÔrquicos usando o SQLAlchemy ORM.
Listagem de arquivos:

Conjuntos aninhados 

Ilustra uma maneira rudimentar de implementar o padrão de "conjuntos aninhados" para dados hierÔrquicos usando o SQLAlchemy ORM.
Listagem de arquivos:

  • nested_sets.py - Estrutura em Ć”rvore dos "conjuntos aninhados" da Celko.

Desempenho 

Um conjunto de perfis de desempenho para uma variedade de casos de uso SQLAlchemy.
Cada conjunto se concentra em um caso de uso especƭfico com um perfil de desempenho especƭfico e implicaƧƵes associadas:
  • inserƧƵes em massa
  • inserƧƵes individuais, com ou sem transaƧƵes
  • buscando um grande nĆŗmero de linhas
  • executando muitas consultas curtas
Todos os conjuntos incluem uma variedade de padrões de uso que ilustram o uso do Core e do ORM e geralmente são classificados em ordem de desempenho do pior para o maior, inversamente com base na quantidade de funcionalidade fornecida pelo SQLAlchemy, do maior para o menor (essas duas coisas geralmente correspondem perfeitamente).
Uma ferramenta de linha de comando Ć© apresentada no nĆ­vel do pacote que permite que conjuntos individuais sejam executados:
$ python -m examples.performance --help
usage: python -m examples.performance [-h] [--test TEST] [--dburl DBURL]
                                      [--num NUM] [--profile] [--dump]
                                      [--runsnake] [--echo]

                                      {bulk_inserts,large_resultsets,single_inserts}

positional arguments:
  {bulk_inserts,large_resultsets,single_inserts}
                        suite to run

optional arguments:
  -h, --help            show this help message and exit
  --test TEST           run specific test name
  --dburl DBURL         database URL, default sqlite:///profile.db
  --num NUM             Number of iterations/items/etc for tests;
                        default is module-specific
  --profile             run profiling and dump call counts
  --dump                dump full call profile (implies --profile)
  --runsnake            invoke runsnakerun (implies --profile)
  --echo                Echo SQL output
Um exemplo de execução é semelhante a:
$ python -m examples.performance bulk_inserts
Ou com opƧƵes:
$ python -m examples.performance bulk_inserts \
    --dburl mysql+mysqldb://scott:tiger@localhost/test \
    --profile --num 1000

Listagem de arquivos 

Listagem de arquivos:

  • bulk_updates.py - Essa sĆ©rie de testes ilustra maneiras diferentes de atualizar um grande nĆŗmero de linhas em massa.

  • large_resultsets.py - Nesta sĆ©rie de testes, estamos aguardando o momento para carregar um grande nĆŗmero de linhas muito pequenas e simples.

  • bulk_inserts.py - Esta sĆ©rie de testes ilustra maneiras diferentes de INSERIR um grande nĆŗmero de linhas em massa.

  • short_selects.py - Esta sĆ©rie de testes ilustra maneiras diferentes de selecionar um Ćŗnico registro pela chave primĆ”ria

  • single_inserts.py - Nesta sĆ©rie de testes, estamos analisando um mĆ©todo que insere uma linha em uma transação distinta e, posteriormente, retorna ao estado essencialmente "fechado". Isso seria anĆ”logo a uma chamada de API que inicia uma conexĆ£o com o banco de dados, insere a linha, confirma e fecha.

  • __main__.py - Permite que o pacote de exemplos / desempenho seja executado como um script.

Executando todos os testes com o tempo 

Esta é a forma padrão de execução:
$ python -m examples.performance single_inserts
Tests to run: test_orm_commit, test_bulk_save,
              test_bulk_insert_dictionaries, test_core,
              test_core_query_caching, test_dbapi_raw_w_connect,
              test_dbapi_raw_w_pool

test_orm_commit : Individual INSERT/COMMIT pairs via the
    ORM (10000 iterations); total time 13.690218 sec
test_bulk_save : Individual INSERT/COMMIT pairs using
    the "bulk" API  (10000 iterations); total time 11.290371 sec
test_bulk_insert_dictionaries : Individual INSERT/COMMIT pairs using
    the "bulk" API with dictionaries (10000 iterations);
    total time 10.814626 sec
test_core : Individual INSERT/COMMIT pairs using Core.
    (10000 iterations); total time 9.665620 sec
test_core_query_caching : Individual INSERT/COMMIT pairs using Core
    with query caching (10000 iterations); total time 9.209010 sec
test_dbapi_raw_w_connect : Individual INSERT/COMMIT pairs w/ DBAPI +
    connection each time (10000 iterations); total time 9.551103 sec
test_dbapi_raw_w_pool : Individual INSERT/COMMIT pairs w/ DBAPI +
    connection pool (10000 iterations); total time 8.001813 sec

Despejando perfis para testes individuais 

Uma saĆ­da de perfil Python pode ser descarregada para todos os testes ou, geralmente, para testes individuais:
$ python -m examples.performance single_inserts --test test_core --num 1000 --dump
Tests to run: test_core
test_core : Individual INSERT/COMMIT pairs using Core. (1000 iterations); total fn calls 186109
         186109 function calls (186102 primitive calls) in 1.089 seconds

   Ordered by: internal time, call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1000    0.634    0.001    0.634    0.001 {method 'commit' of 'sqlite3.Connection' objects}
     1000    0.154    0.000    0.154    0.000 {method 'execute' of 'sqlite3.Cursor' objects}
     1000    0.021    0.000    0.074    0.000 /Users/classic/dev/sqlalchemy/lib/sqlalchemy/sql/compiler.py:1950(_get_colparams)
     1000    0.015    0.000    0.034    0.000 /Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/default.py:503(_init_compiled)
        1    0.012    0.012    1.091    1.091 examples/performance/single_inserts.py:79(test_core)

    ...

Usando RunSnake 

Esta opção requer que a ferramenta de linha de comando RunSnake esteja instalada:
$ python -m examples.performance single_inserts --test test_core --num 1000 --runsnake
Uma saƭda grƔfica do RunSnake serƔ exibida.

Escrevendo suas próprias suĆ­tes 

O sistema do conjunto de profiler Ć© extensĆ­vel e pode ser aplicado ao seu próprio conjunto de testes. Essa Ć© uma tĆ©cnica valiosa a ser usada na decisĆ£o da abordagem adequada para algum conjunto de rotinas crĆ­ticas ao desempenho. Por exemplo, se quisermos criar um perfil da diferenƧa entre vĆ”rios tipos de carregamento, podemos criar um arquivo test_loads.pycom o seguinte conteĆŗdo:
from examples.performance import Profiler
from sqlalchemy import Integer, Column, create_engine, ForeignKey
from sqlalchemy.orm import relationship, joinedload, subqueryload, Session
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = None
session = None


class Parent(Base):
    __tablename__ = 'parent'
    id = Column(Integer, primary_key=True)
    children = relationship("Child")


class Child(Base):
    __tablename__ = 'child'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('parent.id'))


# Init with name of file, default number of items
Profiler.init("test_loads", 1000)


@Profiler.setup_once
def setup_once(dburl, echo, num):
    "setup once.  create an engine, insert fixture data"
    global engine
    engine = create_engine(dburl, echo=echo)
    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)
    sess = Session(engine)
    sess.add_all([
        Parent(children=[Child() for j in range(100)])
        for i in range(num)
    ])
    sess.commit()


@Profiler.setup
def setup(dburl, echo, num):
    "setup per test.  create a new Session."
    global session
    session = Session(engine)
    # pre-connect so this part isn't profiled (if we choose)
    session.connection()


@Profiler.profile
def test_lazyload(n):
    "load everything, no eager loading."

    for parent in session.query(Parent):
        parent.children


@Profiler.profile
def test_joinedload(n):
    "load everything, joined eager loading."

    for parent in session.query(Parent).options(joinedload("children")):
        parent.children


@Profiler.profile
def test_subqueryload(n):
    "load everything, subquery eager loading."

    for parent in session.query(Parent).options(subqueryload("children")):
        parent.children

if __name__ == '__main__':
    Profiler.main()
Podemos executar nosso novo script diretamente:
$ python test_loads.py  --dburl postgresql+psycopg2://scott:tiger@localhost/test
Running setup once...
Tests to run: test_lazyload, test_joinedload, test_subqueryload
test_lazyload : load everything, no eager loading. (1000 iterations); total time 11.971159 sec
test_joinedload : load everything, joined eager loading. (1000 iterations); total time 2.754592 sec
test_subqueryload : load everything, subquery eager loading. (1000 iterations); total time 2.977696 sec
AlƩm de ver a saƭda do RunSnake para um teste individual:
$ python test_loads.py  --num 100 --runsnake --test test_joinedload

CondiƧƵes de junção de relacionamento 

Exemplos de vĆ”rias orm.relationship()configuraƧƵes, que fazem uso do primaryjoinargumento para compor tipos especiais de condiƧƵes de junção.
Listagem de arquivos:

  • threeway.py - Ilustre uma ā€œjunção de trĆŖs viasā€ - onde uma tabela principal se une a uma tabela remota por meio de uma tabela de associação, mas a tabela principal tambĆ©m precisa se referir a algumas colunas diretamente na tabela remota.

  • cast.py - Ilustre um relationship()que une duas colunas em que essas colunas nĆ£o sĆ£o do mesmo tipo e um CAST deve ser usado no lado do SQL para correspondĆŖ-las.

Space Invaders 

Um jogo Space Invaders usando SQLite como mƔquina de estado.
Originalmente desenvolvido em 2012. Adaptado para trabalhar em Python 3.
Ɖ executado em um console de texto usando arte ASCII.
../_images/space_invaders.jpgPara correr:
python -m examples.space_invaders.space_invaders
Enquanto Ć© executado, observe a saĆ­da SQL no log:
tail -f space_invaders.log
aproveitar!
Listagem de arquivos:

XML PersistĆŖncia 

Ilustra trĆŖs estratĆ©gias para persistir e consultar documentos XML, conforme representado pelo ElementTree em um banco de dados relacional. As tĆ©cnicas nĆ£o aplicam nenhum mapeamento aos objetos ElementTree diretamente, portanto, sĆ£o compatĆ­veis com o cElementTree nativo e com o lxml e podem ser adaptados para se adequar a qualquer tipo de sistema de representação DOM. A consulta ao longo de seqüências semelhantes a xpath tambĆ©m Ć© ilustrada.
Ex .:
# parse an XML file and persist in the database
doc = ElementTree.parse("test.xml")
session.add(Document(file, doc))
session.commit()

# locate documents with a certain path/attribute structure
for document in find_document('/somefile/header/field2[@attr=foo]'):
    # dump the XML
    print document
Listagem de arquivos:

  • pickle_type.py - ilustra uma maneira rĆ”pida e suja de manter um documento XML expresso usando ElementTree e pickle.

  • adjacency_list.py - ilustra uma maneira explĆ­cita de manter um documento XML expresso usando o ElementTree.

  • optimized_al.py - Usa a mesma estratĆ©gia de adjacency_list.py, mas associa cada linha do DOM Ć  sua própria linha de documento, para que um documento completo dos nós do DOM possa ser carregado usando consultas O (1) - a construção da "hierarquia" Ć© executada após o carregar de forma nĆ£o recursiva e Ć© mais eficiente.

Versionamento Objects 


Controle de versĆ£o com uma tabela de histórico 

Ilustra uma extensĆ£o que cria tabelas de versƵes para entidades e armazena registros para cada alteração. As extensƵes fornecidas geram uma classe "history" anĆ“nima que representa versƵes históricas do objeto de destino.
Compare com os exemplos de controle de versĆ£o usando Linhas Temporais que gravam atualizaƧƵes como novas linhas na mesma tabela, sem usar uma tabela de histórico separada.
O uso Ć© ilustrado atravĆ©s de um módulo de teste de unidade test_versioning.py, que pode ser executado atravĆ©s de py.test:
# assume SQLAlchemy is installed where py.test is

cd examples/versioned_history
py.test test_versioning.py
Um fragmento de exemplo de uso, usando declarativo:
from history_meta import Versioned, versioned_session

Base = declarative_base()

class SomeClass(Versioned, Base):
    __tablename__ = 'sometable'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))

    def __eq__(self, other):
        assert type(other) is SomeClass and other.id == self.id

Session = sessionmaker(bind=engine)
versioned_session(Session)

sess = Session()
sc = SomeClass(name='sc1')
sess.add(sc)
sess.commit()

sc.name = 'sc1modified'
sess.commit()

assert sc.version == 2

SomeClassHistory = SomeClass.__history_mapper__.class_

assert sess.query(SomeClassHistory).\
            filter(SomeClassHistory.version == 1).\
            all() \
            == [SomeClassHistory(version=1, name='sc1')]
Versionedmixin Ć© projetado para funcionar com declarativo. Para usar a extensĆ£o com mapeadores clĆ”ssicos, a _history_mapperfunção pode ser aplicada:
from history_meta import _history_mapper

m = mapper(SomeClass, sometable)
_history_mapper(m)

SomeHistoryClass = SomeClass.__history_mapper__.class_
Listagem de arquivos:

Controle de versĆ£o usando linhas temporais 

VÔrios exemplos que ilustram a técnica de interceptar alterações que seriam primeiro interpretadas como um UPDATE em uma linha e, em vez disso, transformÔ-lo em um INSERT de uma nova linha, deixando a linha anterior intacta como uma versão histórica.
Compare com o exemplo Controle de versĆ£o com uma tabela de históricoque grava uma linha do histórico em uma tabela de histórico separada.
Listagem de arquivos:

  • versioned_rows.py - ilustra um mĆ©todo para interceptar alteraƧƵes em objetos, transformando uma instrução UPDATE em uma Ćŗnica linha em uma instrução INSERT, para que uma nova linha seja inserida com os novos dados, mantendo a linha antiga intacta.

  • versioned_rows_w_versionid.py - ilustra um mĆ©todo para interceptar alteraƧƵes em objetos, transformando uma instrução UPDATE em uma Ćŗnica linha em uma instrução INSERT, para que uma nova linha seja inserida com os novos dados, mantendo a linha antiga intacta.

  • versioned_map.py - Uma variante do exemplo versioned_rows criada em torno do conceito de uma estrutura de "tabela vertical", como as ilustradas nos exemplos do Vertical Attribute Mapping .

  • versioned_update_old_row.py - Ilustra a mesma tĆ©cnica UPDATE into INSERT de versioned_rows.py, mas tambĆ©m emite uma UPDATE na linha antiga para afetar uma alteração no carimbo de data / hora. TambĆ©m inclui um QueryEvents.before_compile()gancho para limitar as consultas apenas Ć  versĆ£o mais recente.

Mapeamento Vertical de Atributos 

Ilustra os mapeamentos da ā€œtabela verticalā€.
Uma ā€œtabela verticalā€ refere-se a uma tĆ©cnica em que atributos individuais de um objeto sĆ£o armazenados como linhas distintas em uma tabela. A tĆ©cnica ā€œtabela verticalā€ Ć© usada para persistir objetos que podem ter um conjunto variado de atributos, Ć s custas do controle e da concisĆ£o simples da consulta. Ć‰ comumente encontrado em sistemas de gerenciamento de conteĆŗdo / documento para representar estruturas criadas pelo usuĆ”rio de maneira flexĆ­vel.
Duas variantes na abordagem sĆ£o dadas. Na segunda, cada linha faz referĆŖncia a um "tipo de dados" que contĆ©m informaƧƵes sobre o tipo de informação armazenada no atributo, como nĆŗmero inteiro, sequĆŖncia ou data.
Exemplo:
shrew = Animal(u'shrew')
shrew[u'cuteness'] = 5
shrew[u'weasel-like'] = False
shrew[u'poisonous'] = True

session.add(shrew)
session.flush()

q = (session.query(Animal).
     filter(Animal.facts.any(
       and_(AnimalFact.key == u'weasel-like',
            AnimalFact.value == True))))
print 'weasel-like animals', q.all()
Listagem de arquivos:

  • dictlike-polymorphic.py - Mapeando uma tabela vertical com valor polimórfico como um dicionĆ”rio.

  • dictlike.py - Mapeando uma tabela vertical como um dicionĆ”rio.

Receitas de mapeamento de heranƧa 


Mapeamentos bĆ”sicos de heranƧa 

Exemplos de trabalho de heranƧa de tabela Ćŗnica, tabela unida e tabela de concreto, conforme descrito em Hierarquias de heranƧa de classe de mapeamento .
Listagem de arquivos:

  • join.py - Exemplo de heranƧa de tabela unida (tabela por subclasse).

  • concrete.py - BetĆ£o-tabela (tabela-per-classe) exemplo heranƧa.

  • single.py - Exemplo de heranƧa de tabela Ćŗnica (tabela por hierarquia).

APIs especiais 


Instrumentação de Atributos 

Exemplos que ilustram modificaƧƵes no sistema de gerenciamento de atributos do SQLAlchemy.
Listagem de arquivos:

Sharding Horizontal 

Um exemplo bĆ”sico de uso da API SQLAlchemy Sharding. O sharding refere-se Ć  escala horizontal de dados em vĆ”rios bancos de dados.
Os componentes bÔsicos de um mapeamento "fragmentado" são:
  • vĆ”rios bancos de dados, cada um com um 'shard id'
  • uma função que pode retornar um Ćŗnico ID de fragmento, dada uma instĆ¢ncia a ser salva; isso Ć© chamado de "shard_chooser"
  • uma função que pode retornar uma lista de IDs de shard que se aplicam a um identificador de instĆ¢ncia especĆ­fico; isso Ć© chamado de "id_chooser". Se retornar todos os IDs de shard, todos os shards serĆ£o pesquisados.
  • uma função que pode retornar uma lista de IDs de shard para tentar, dada uma consulta especĆ­fica ("query_chooser"). Se retornar todos os IDs de shard, todos os shards serĆ£o consultados e os resultados serĆ£o reunidos.
Neste exemplo, quatro bancos de dados sqlite armazenam informaƧƵes sobre dados meteorológicos em uma base de dados por continente. Nós fornecemos exemplos das funƧƵes shard_chooser, id_chooser e query_chooser. O query_chooser ilustra a inspeção do elemento de expressĆ£o SQL para tentar determinar um Ćŗnico shard que estĆ” sendo solicitado.
A construção de rotinas genĆ©ricas de fragmentação Ć© uma abordagem ambiciosa para a questĆ£o da organização de instĆ¢ncias entre vĆ”rios bancos de dados. Para uma alternativa mais clara, a abordagem "entidade distinta" Ć© um mĆ©todo simples de atribuir objetos a diferentes tabelas (e potencialmente nós do banco de dados) de maneira explĆ­cita - descrita no wiki em EntityName .
Listagem de arquivos:

Estendendo o ORM 


Cache de Dogpile 

Ilustra como incorporar a funcionalidade dogpile.cache ao Queryobjeto, permitindo o controle total do cache, bem como a capacidade de extrair atributos de "carregamento lento" do cache de longo prazo.
Nesta demonstração, as seguintes técnicas são ilustradas:
  • Usando subclasses personalizadas de Query
  • TĆ©cnica bĆ”sica de contornar a consulta para extrair de uma fonte de cache personalizada em vez do banco de dados.
  • Cache rudimentar com dogpile.cache, usando "regiƵes" que permitem controle global sobre um conjunto fixo de configuraƧƵes.
  • Usando MapperOptionobjetos personalizados para configurar opƧƵes em uma Consulta, incluindo a capacidade de chamar as opƧƵes em profundidade em um grĆ”fico de objeto quando ocorrem cargas preguiƧosas.
Ex .:
# query for Person objects, specifying cache
q = Session.query(Person).options(FromCache("default"))

# specify that each Person's "addresses" collection comes from
# cache too
q = q.options(RelationshipCache(Person.addresses, "default"))

# query
print q.all()
Para executar, o SQLAlchemy e o dogpile.cache devem estar instalados ou no PYTHONPATH atual. A demonstração criarĆ” um diretório local para os arquivos de dados, inserirĆ” os dados iniciais e executarĆ”. A execução da demonstração pela segunda vez utilizarĆ” os arquivos de cache jĆ” presentes, e exatamente uma instrução SQL em duas tabelas serĆ” emitida - o resultado exibido, no entanto, utilizarĆ” dezenas de cargas preguiƧosas que sĆ£o extraĆ­das do cache.
Os próprios scripts de demonstração, em ordem de complexidade, são executados como módulos Python, para que as importações relativas funcionem:
python -m examples.dogpile_caching.helloworld

python -m examples.dogpile_caching.relationship_caching

python -m examples.dogpile_caching.advanced

python -m examples.dogpile_caching.local_session_caching
Listagem de arquivos:

  • environment.py - EstabeleƧa caminhos e configuraƧƵes de arquivo de dados / cache, dados do dispositivo de inicialização, se necessĆ”rio.

  • caching_query.py - Representa funƧƵes e classes que permitem o uso do armazenamento em cache Dogpile com SQLAlchemy. Apresenta uma opção de consulta chamada FromCache.

  • model.py - O modelo de dados, que representa a Pessoa que possui vĆ”rios objetos de EndereƧo, cada um com Código Postal, Cidade, PaĆ­s.

  • fixture_data.py - Instala alguns dados de amostra. Aqui temos alguns códigos postais para algumas cidades dos EUA / CanadĆ”. Em seguida, 100 registros de Pessoa sĆ£o instalados, cada um com um código postal selecionado aleatoriamente.

  • helloworld.py - Ilustre como carregar alguns dados e armazenar em cache os resultados.

  • relationship_caching.py - Ilustra como adicionar opƧƵes de cache nos pontos de extremidade do relacionamento, para que o lazyload seja carregado do cache.

  • advanced.py - Ilustra o uso de Query combinado com a opção FromCache, incluindo carregamento de front-end, invalidação de cache e armazenamento em cache de coleção.

  • local_session_caching.py - Este exemplo cria um novo backend dogpile.cache que manterĆ” os dados em um dicionĆ”rio local da sessĆ£o atual. remove () a sessĆ£o e o cache se foi.

Integração PostGIS 

Um exemplo ingênuo que ilustra técnicas para ajudar a incorporar a funcionalidade PostGIS.
Este exemplo foi desenvolvido originalmente na esperanƧa de que fosse extrapolado para uma camada abrangente de integração do PostGIS. Temos o prazer de anunciar que isso se concretizou como GeoAlquimia .
O exemplo ilustra:
  • uma extensĆ£o DDL que permite que CREATE / DROP funcione em conjunto com AddGeometryColumn / DropGeometryColumn
  • um tipo de geometria, alĆ©m de alguns subtipos, que convertem os valores da linha de resultado em um objeto que reconhece GIS e tambĆ©m se integra Ć  extensĆ£o DDL.
  • um objeto que reconhece GIS que armazena um valor de geometria bruta e fornece uma fĆ”brica para funƧƵes como AsText ().
  • um comparador ORM que pode substituir mĆ©todos de coluna padrĆ£o em objetos mapeados para produzir operadores GIS.
  • um ouvinte de evento de atributo que intercepta cadeias e converte em GeomFromText ().
  • um exemplo de operador independente.
A implementação é limitada apenas a pontos de extensão públicos, conhecidos e simples de usar.
Ex .:
print session.query(Road).filter(
    Road.road_geom.intersects(r1.road_geom)).all()
Listagem de arquivos:

Postar um comentƔrio

0 ComentƔrios