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:

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