{ "info": { "author": "Paylogic International", "author_email": "developers@paylogic.com", "bugtrack_url": null, "classifiers": [], "description": "metalchemy: SQLAlchemy hierarchical key/value helper\n====================================================\n\nThe ``metalchemy`` package provides helpers for your SQLAlchemy models to add dynamic properties.\n\n.. image:: https://api.travis-ci.org/paylogic/metalchemy.png\n :target: https://travis-ci.org/paylogic/metalchemy\n.. image:: https://pypip.in/v/metalchemy/badge.png\n :target: https://crate.io/packages/metalchemy/\n.. image:: https://coveralls.io/repos/paylogic/metalchemy/badge.png?branch=master\n :target: https://coveralls.io/r/paylogic/metalchemy\n\n\nInstallation\n------------\n\n.. code-block:: sh\n\n pip install metalchemy\n\n\nUsage\n-----\n\nmetalchemy usage example:\n\n.. code-block:: python\n\n from sqlalchemy.ext.declarative import declarative_base\n\n Base = declarative_base()\n\n import metalchemy\n\n metalchemy_attributes = metalchemy.initialize(Base)\n\n Session = sessionmaker(bind=engine)\n sess = Session()\n\n class MyModel(Base)\n\n meta = metalchemy_attributes.Metadata()\n\n\n my_object = MyModel()\n my_object.meta.some.value = 'some value'\n sess.add(my_object)\n sess.commit()\n\n sess.refresh(my_object)\n assert my_object.meta.some.value.get_value() == 'some value'\n\n\nIn order to give a class metadata capabilities, add a single class attribute to it which is an instance\nof :\n\n.. code-block:: python\n\n class HasMetadata(object):\n meta = metadata.Metadata()\n\nAny instance of this class will now have its metadata accessible via the *meta* attribute.\n\nSuch meta attributes allow free reading and assigning of attributes, with no limits on the depth of the attributes.\ni.e., meta.foo is always available for reading and writing, but also meta.foo.bar.baz, without any setup beforehand.\n\nAssigning to a metadata property is simple and\nobvious:\n\n.. code-block:: python\n\n inst.meta.foo = 42\n inst.meta.foo.bar.baz = 'qux'\n\nAny metadata attribute is also implicitly an array. It is possible to assign and read from any\nindex:\n\n.. code-block:: python\n\n inst.meta.foo[0] = 42\n inst.meta.foo[1] = 'baz'\n inst.meta.foo[1].bar = 'qux'\n inst.meta.foo[1].spam[2] = 'eggs'\n inst.meta.foo[1][2] = 'xyzzy'\n\nAny non-indexed attribute is implicitly converted to an index of zero.\n\nAll metadata values are converted to unicode strings on assignment. Assigned values are automatically added to\nthe SQLAlchemy session, but not committed, so remember to execute session.commit().\nFurthermore, the methods `FieldWrapper.append`, `FieldWrapper.iteritems` and `FieldWrapper.__iter__`\nare supported as well for direct iteration.\n\nReading the value back requires using `get_value` method:\n\n.. code-block:: python\n\n inst.meta.foo.get_value() # returns 42\n inst.meta.foo.bar.baz.get_value() # returns u'qux'\n\nInternals:\nThe hierarchical structure of the fields is stored in an adjacency list (represented by <_Fields>), which is unique\nfor a single class. All instances of a class share this same tree. An <_Object> maps the class name to this tree,\nand is set up to have the entire tree load at once when it is needed.\n\nThe instance assigned to a container class will load the <_Object> (and implicitly, the field hierarchy)\non access and return a wrapped root node.\n\n wrap each <_Field>, performing two functions:\n- They allow accessing fields that have no concrete <_Field> instance yet, creating these as necessary\n- They actually access the values list of a specific container class instance.\n\nValues are stored in a flat list, which is loaded entirely for the container class instane when it is first needed.\n\nArray support is handled by having two states of `FieldWrappers`: regular and indexed.\n\nA regular wrapper wraps an unindexed attribute. It handles reading and writing of array elements on its attribute\n(`FieldWrapper.__getitem__` and `FieldWrapper.__setitem__`), and defers attribute access to its own zeroth index.\n\nAn indexed wrapper wraps an indexed attribute. This wrapper handles attribute access by returning a wrapper for that\nchild attribute. Indexed wrappers can also be indexed, but this is internally done by deferring the secondary index\nto a hidden child attribute. i.e. accessing `meta.foo[0][1][2]` is internally handled as accessing\n`meta.foo[0].[1].[2]`.\n\n.. warning::\n\n * Before metadata is assigned, primary key must have been set to its value. This means they must be at least flushed once before assigning metadata.\n\n\nContact\n-------\n\nIf you have questions, bug reports, suggestions, etc. please create an issue on\nthe `GitHub project page `_.\n\n\nLicense\n-------\n\nThis software is licensed under the `MIT license `_\n\nSee `License `_\n\n\n\u00a9 2014 Paylogic International.\n\nChangelog\n=========\n\n\n1.0.0\n-----\n\n* Initial public release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/paylogic/metalchemy", "keywords": "sqlalchemy dynamic object fields metadata key/value", "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "metalchemy", "package_url": "https://pypi.org/project/metalchemy/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/metalchemy/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/paylogic/metalchemy" }, "release_url": "https://pypi.org/project/metalchemy/1.0.0/", "requires_dist": null, "requires_python": null, "summary": "SQLAlchemy hierarchical key/value helper", "version": "1.0.0" }, "last_serial": 1301001, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "992ac30f7763674620b06d36d53f7655", "sha256": "5e22626166dfcd27f708bb58837a61e61901e2fdadb68a4a97d295ad7193d733" }, "downloads": -1, "filename": "metalchemy-1.0.0.tar.gz", "has_sig": false, "md5_digest": "992ac30f7763674620b06d36d53f7655", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10402, "upload_time": "2014-11-10T13:41:51", "url": "https://files.pythonhosted.org/packages/43/a5/3c3e31ba2e1f633c6126b0130b0da9b6d13ab8b22b65dbca2839af7d25f6/metalchemy-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "992ac30f7763674620b06d36d53f7655", "sha256": "5e22626166dfcd27f708bb58837a61e61901e2fdadb68a4a97d295ad7193d733" }, "downloads": -1, "filename": "metalchemy-1.0.0.tar.gz", "has_sig": false, "md5_digest": "992ac30f7763674620b06d36d53f7655", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10402, "upload_time": "2014-11-10T13:41:51", "url": "https://files.pythonhosted.org/packages/43/a5/3c3e31ba2e1f633c6126b0130b0da9b6d13ab8b22b65dbca2839af7d25f6/metalchemy-1.0.0.tar.gz" } ] }