Skip to main content

metalchemy: SQLAlchemy hierarchical key/value helper

The metalchemy package provides helpers for your SQLAlchemy models to add dynamic properties.

https://api.travis-ci.org/paylogic/metalchemy.png https://pypip.in/v/metalchemy/badge.png https://coveralls.io/repos/paylogic/metalchemy/badge.png?branch=master

Installation

pip install metalchemy

Usage

metalchemy usage example:

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

import metalchemy

metalchemy_attributes = metalchemy.initialize(Base)

Session = sessionmaker(bind=engine)
sess = Session()

class MyModel(Base)

    meta = metalchemy_attributes.Metadata()


my_object = MyModel()
my_object.meta.some.value = 'some value'
sess.add(my_object)
sess.commit()

sess.refresh(my_object)
assert  my_object.meta.some.value.get_value() == 'some value'

In order to give a class metadata capabilities, add a single class attribute to it which is an instance of <Metadata>:

class HasMetadata(object):
    meta = metadata.Metadata()

Any instance of this class will now have its metadata accessible via the meta attribute.

Such meta attributes allow free reading and assigning of attributes, with no limits on the depth of the attributes. i.e., meta.foo is always available for reading and writing, but also meta.foo.bar.baz, without any setup beforehand.

Assigning to a metadata property is simple and obvious:

inst.meta.foo = 42
inst.meta.foo.bar.baz = 'qux'

Any metadata attribute is also implicitly an array. It is possible to assign and read from any index:

inst.meta.foo[0] = 42
inst.meta.foo[1] = 'baz'
inst.meta.foo[1].bar = 'qux'
inst.meta.foo[1].spam[2] = 'eggs'
inst.meta.foo[1][2] = 'xyzzy'

Any non-indexed attribute is implicitly converted to an index of zero.

All metadata values are converted to unicode strings on assignment. Assigned values are automatically added to the SQLAlchemy session, but not committed, so remember to execute session.commit(). Furthermore, the methods FieldWrapper.append, FieldWrapper.iteritems and FieldWrapper.__iter__ are supported as well for direct iteration.

Reading the value back requires using get_value method:

inst.meta.foo.get_value()  # returns 42
inst.meta.foo.bar.baz.get_value()  # returns u'qux'

Internals: The hierarchical structure of the fields is stored in an adjacency list (represented by <_Fields>), which is unique for a single class. All instances of a class share this same tree. An <_Object> maps the class name to this tree, and is set up to have the entire tree load at once when it is needed.

The <Metadata> instance assigned to a container class will load the <_Object> (and implicitly, the field hierarchy) on access and return a wrapped root node.

<FieldWrappers> wrap each <_Field>, performing two functions: - They allow accessing fields that have no concrete <_Field> instance yet, creating these as necessary - They actually access the values list of a specific container class instance.

Values are stored in a flat list, which is loaded entirely for the container class instane when it is first needed.

Array support is handled by having two states of FieldWrappers: regular and indexed.

A regular wrapper wraps an unindexed attribute. It handles reading and writing of array elements on its attribute (FieldWrapper.__getitem__ and FieldWrapper.__setitem__), and defers attribute access to its own zeroth index.

An indexed wrapper wraps an indexed attribute. This wrapper handles attribute access by returning a wrapper for that child attribute. Indexed wrappers can also be indexed, but this is internally done by deferring the secondary index to a hidden child attribute. i.e. accessing meta.foo[0][1][2] is internally handled as accessing meta.foo[0].<hidden>[1].<hidden>[2].

Contact

If you have questions, bug reports, suggestions, etc. please create an issue on the GitHub project page.

License

This software is licensed under the MIT license

See License

© 2014 Paylogic International.

Changelog

1.0.0

  • Initial public release

Metadata

Release files for metalchemy 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for metalchemy 1.0.0
File Size Uploaded
metalchemy-1.0.0.tar.gz 10.4 kB Details

Release files / metalchemy-1.0.0.tar.gz

Download URL metalchemy-1.0.0.tar.gz
Size 10.4 kB
Tags Source
SHA-256 checksum
How to use checksums
5e22626166dfcd27f708bb58837a61e61901e2fdadb68a4a97d295ad7193d733
BLAKE2b-256 checksum
How to use checksums
43a53c3e31ba2e1f633c6126b0130b0da9b6d13ab8b22b65dbca2839af7d25f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

This release

1.0.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page