{ "info": { "author": "lzyy", "author_email": "healdream@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Database", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "
\n     /\\  \\         /\\__\\          ___        /\\__\\         /\\  \\    \n     \\:\\  \\       /:/  /         /\\  \\      /::|  |       /::\\  \\   \n      \\:\\  \\     /:/__/          \\:\\  \\    /:|:|  |      /:/\\:\\  \\  \n      /::\\  \\   /::\\  \\ ___      /::\\__\\  /:/|:|  |__   /:/  \\:\\  \\ \n     /:/\\:\\__\\ /:/\\:\\  /\\__\\  __/:/\\/__/ /:/ |:| /\\__\\ /:/__/_\\:\\__\\\n    /:/  \\/__/ \\/__\\:\\/:/  / /\\/:/  /    \\/__|:|/:/  / \\:\\  /\\ \\/__/\n   /:/  /           \\::/  /  \\::/__/         |:/:/  /   \\:\\ \\:\\__\\  \n   \\/__/            /:/  /    \\:\\__\\         |::/  /     \\:\\/:/  /  \n                   /:/  /      \\/__/         /:/  /       \\::/  /   \n                   \\/__/                     \\/__/         \\/__/    \n\n
\n\n# Thing \u662f\u4ec0\u4e48\uff1f\n\nThing\u662f\u4e00\u4e2a\u57fa\u4e8eSQLAlchemy\u7684\u914d\u7f6e\u7b80\u5355\u3001\u4f7f\u7528\u7b80\u5355\u4e14\u7075\u6d3b\u7684ORM\u3002\n\n# \u4f7f\u7528\u65b9\u6cd5\n\n\u4e3e\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u5047\u5982\u67093\u4e2a\u8868\uff1acomment, post, user, 3\u4e2a\u8868\u7684\u5b57\u6bb5\u5206\u522b\u662f\uff1a\n\ncomment\u8868:\n```\n+---------+------------------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+---------+------------------+------+-----+---------+----------------+\n| id | int(11) unsigned | NO | PRI | NULL | auto_increment |\n| user_id | int(11) | YES | MUL | NULL | |\n| post_id | int(11) | YES | MUL | NULL | |\n| content | text | YES | | NULL | |\n+---------+------------------+------+-----+---------+----------------+\n```\n\npost\u8868\uff1a\n```\n+---------+------------------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+---------+------------------+------+-----+---------+----------------+\n| id | int(11) unsigned | NO | PRI | NULL | auto_increment |\n| user_id | int(11) | YES | MUL | NULL | |\n| created | int(11) | YES | | NULL | |\n| content | text | YES | | NULL | |\n| title | varchar(255) | YES | | NULL | |\n+---------+------------------+------+-----+---------+----------------+\n```\n\nuser\u8868\uff1a\n```\n+-------+------------------+------+-----+---------+----------------+\n| Field | Type | Null | Key | Default | Extra |\n+-------+------------------+------+-----+---------+----------------+\n| id | int(11) unsigned | NO | PRI | NULL | auto_increment |\n| name | varchar(30) | YES | | NULL | |\n+-------+------------------+------+-----+---------+----------------+\n```\n\n## \u5b9a\u4e49Model\n\n\u5148\u6765\u770b\u770b\u76ee\u5f55\u7ed3\u6784\n```\n\u251c\u2500\u2500 __init.py__\n\u251c\u2500\u2500 conn.py # \u7528\u4e8e\u6570\u636e\u5e93\u8fde\u63a5\n\u251c\u2500\u2500 models\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 comment.py\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 post.py\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 user.py\n\u2514\u2500\u2500 test.py\n```\ntest.py\u5c31\u662f\u8fdb\u884c\u6d4b\u8bd5\u7684\u5730\u65b9\uff0c\u5148\u6765\u770b\u770b\u5404\u4e2amodel\u7684\u5185\u5bb9\uff1a\n\n### comment.py\n\n```\nfrom thing import thing\n\nclass Comment(thing.Thing):\n _belongs_to = {\n 'post': {\n 'model': 'models.post.Post',\n 'foreign_key': 'post_id',\n },\n 'author': {\n 'model': 'models.user.User',\n 'foreign_key': 'user_id',\n },\n }\n```\n\n### post.py\n\n```\nfrom thing import thing\n\nclass Post(thing.Thing):\n _belongs_to = {\n 'author': {\n 'model': 'models.user.User',\n 'foreign_key': 'user_id',\n }\n }\n _has_many = {\n 'comments': {\n 'model': 'models.comment.Comment',\n 'foreign_key': 'user_id',\n }\n }\n```\n\n### user.py\n\n```\nfrom thing import thing\n\nclass User(thing.Thing):\n _has_many = {\n 'posts': {\n 'model': 'models.post.Post',\n 'foreign_key': 'user_id'\n },\n 'comments': {\n 'model': 'models.comment.Comment',\n 'foreign_key': 'user_id'\n }\n }\n```\n\n\u518d\u6765\u770b\u770bconn.py\n\n### conn.py\n\n```\nfrom thing import thing\n\nconfig = {\n 'db': {\n 'master': {\n 'url': 'mysql://root:123456@127.0.0.1:3306/test?charset=utf8',\n 'echo': False,\n },\n 'slave': {\n 'url': 'mysql://root:123456@127.0.0.1:3306/test?charset=utf8',\n 'echo': False,\n },\n },\n 'redis': {\n 'host': 'localhost',\n 'port': 6379,\n 'db': 1,\n },\n 'thing': {\n 'debug': True,\n }\n }\n\nthing.Thing.config(config)\n```\n\nOK\uff0c\u4e07\u4e8b\u5177\u5907\uff0c\u5f00\u5de5\uff01\n\n```\nimport conn\nfrom models.comment import Comment\nfrom models.user import User\nfrom models.post import Post\n\n# -------- \u63d2\u5165\u6570\u636e --------\nuser = User()\nuser.name = 'foo'\nuser.save()\n# \u6216\u8005 user = User(name='foo').save()\n\n# -------- \u83b7\u53d6\u6570\u636e --------\nuser = User().find(1)\nprint user.name\n\n# -------- \u83b7\u53d6\u5173\u8054\u6570\u636e -------\nposts = User().find(1).posts.findall()\n# \u5982\u679c\u8981\u8bbe\u7f6eoffset / limit, \u5728findall\u91cc\u52a0\u5165\u53c2\u6570\u5373\u53ef\n# posts = User().find(1).posts.findall(offset = 0, limit = 20)\n\n# ------- \u5220\u9664\u6570\u636e -------\nUser().find(1).delete()\n\n# ------- \u66f4\u65b0\u6570\u636e -------\nuser = User().find(1)\nuser.name = 'bar'\nuser.save()\n```\n\n# \u52a8\u6001\u67e5\u8be2\n\n\u8fd9\u4e2a\u662f\u53d7Rails\u5f71\u54cd\uff0c\u89c9\u5f97\u5f88\u65b9\u4fbf\u5c31\u62ff\u6765\u4e86\u3002\u6bd4\u5982 `Post().count_by_user_id(3)`\uff0c\u5c31\u53ef\u4ee5\u627e\u5230user_id\u4e3a3\u7684\u7528\u6237\u53d1\u8868\u7684\u6587\u7ae0\u6570\u91cf\u3002\u8981\u83b7\u53d6`user_id`\u4e3a3\u7684\u7528\u6237\u53d1\u8868\u7684\u6587\u7ae0\uff0c\u53ef\u4ee5`Post().findall_by_user_id(3, limit=20)`\uff0c\u6bd4\u8d77`Post().where('user_id', '=', 3).findall()`\u66f4\u52a0\u7b80\u6d01\u548c\u660e\u4e86\u3002\n\n# \u5173\u4e8e\u6027\u80fd\u548c\u7f13\u5b58\n\nThing\u5185\u7f6e\u4e86Redis\u4f5c\u4e3a\u7f13\u5b58\uff0c\u4f60\u751a\u81f3\u90fd\u4e0d\u9700\u8981\u77e5\u9053Redis\u7684\u5b58\u5728\uff0c\u6b63\u5e38\u8be5\u600e\u4e48\u7528\u8fd8\u600e\u4e48\u7528\uff0cThing\u4f1a\u81ea\u52a8\u5904\u7406\u7f13\u5b58\u7684\u751f\u6210\u3001\u8bfb\u53d6\u3001\u8fc7\u671f\u3001\u5220\u9664\u7b49\u64cd\u4f5c\u3002\n\n\u5047\u8bbe\u8868post\u91cc\u67095\u6761\u6570\u636e\uff0c\u5728\u83b7\u53d6\u6bcf\u6761post\u540e\uff0c\u8fd8\u60f3\u83b7\u53d6\u8be5post\u5bf9\u5e94\u7684\u7528\u6237\u4fe1\u606f\uff0c\u4ee3\u7801\u5982\u4e0b\uff1a\n\n```\nposts = Post().findall(limit=5)\n\nfor post in posts:\n\tprint post.author\n```\n\n\u5728\u5f00\u542fDebug\u7684\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u5728\u7ec8\u7aef\u770b\u5230\u5982\u4e0b\u663e\u793a\uff1a\n\n```\nDEBUG - [cost:0.0032] - SELECT post.id, post.user_id, post.created, post.content, post.title\nFROM post ORDER BY post.id DESC\nLIMIT :param_1 OFFSET :param_2\nDEBUG - Cache Read: thing.User:1\n{u'id': 1, u'name': u'lzyy'}\nDEBUG - Cache Read: thing.User:1\n{u'id': 1, u'name': u'lzyy'}\nDEBUG - Cache Read: thing.User:1\n{u'id': 1, u'name': u'lzyy'}\nDEBUG - Cache Read: thing.User:1\n{u'id': 1, u'name': u'lzyy'}\nDEBUG - Cache Read: thing.User:1\n{u'id': 1, u'name': u'lzyy'}\n```\n\n\u53ef\u4ee5\u770b\u5230\u7528\u6237\u7684\u4fe1\u606f\u90fd\u662f\u4ece\u7f13\u5b58\u4e2d\u8bfb\u53d6\u7684\uff0c\u6240\u4ee5\u4e0d\u7528\u62c5\u5fc3n+1\u7684\u95ee\u9898\u3002\n\u5047\u5982\u7528\u6237\u7684\u4fe1\u606f\u88ab\u66f4\u65b0\uff0c\u7f13\u5b58\u4e5f\u4f1a\u81ea\u52a8\u66f4\u65b0\u3002\n\n# \u5176\u4ed6\n\n* \u914d\u7f6e\u4fe1\u606f\u91cc\u7684`master`\u548c`slave`\u4e3a\u5fc5\u9009\u9879\uff0c\u53ef\u4ee5\u76f8\u540c\u3002Thing\u4f1a\u6839\u636e\u4e0d\u540c\u7684\u67e5\u8be2\uff0c\u81ea\u52a8\u627e\u5230\u5bf9\u5e94\u7684db\u3002\u5982find/findall\u4f1a\u627eslave\uff0cupdate/delete\u4f1a\u627emaster\u3002\n* \u914d\u7f6e\u4fe1\u606f\u91cc\u7684redis\u9879\u4e3a\u5fc5\u9009\u9879\u3002\n* \u52a8\u6001\u67e5\u8be2\u76ee\u524d\u652f\u6301`find_by`, `findall_by`, `findall_in`, `count_by`\n* \u5185\u7f6e\u4e868\u4e2a\u94a9\u5b50\uff0c\u4f1a\u5728\u76f8\u5e94\u7684\u4e8b\u4ef6\u53d1\u751f\u65f6\u88ab\u8c03\u7528\uff0c\u5206\u522b\u662f\uff1a`_before_insert`,`_after_insert`,`_before_update`,`_after_update`,`_before_delete`,`_after_delete`,`_before_find`,`_after_find`\uff0c\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u8986\u76d6\u8fd9\u4e9b\u65b9\u6cd5\u6765\u5b9e\u73b0\u81ea\u5df1\u7684\u903b\u8f91\u3002\n* \u590d\u6742\u7684SQL\u53ef\u4ee5\u4f7f\u7528`execute`\u65b9\u6cd5\uff0c\u8fd4\u56de\u7684\u7ed3\u679c\u662fSQLAlchemy\u7684ResultProxy\n* \u5982\u679c\u8981\u4e00\u6b21\u66f4\u65b0\u591a\u5904\u7684\u8bdd\uff0c\u53ef\u4ee5\u4f7f\u7528`updateall`\u65b9\u6cd5\uff0c`Post().where('user_id', '=', 1).updateall(user_id=2)`\n* \u8868\u540d\u5982\u679c\u548c\u5c0f\u5199\u7684\u7c7b\u540d\u4e0d\u4e00\u6837\u7684\u8bdd\uff0c\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u91cd\u65b0\u8bbe\u7f6e`_tablename`\n* \u6bcf\u4e2a\u8868\u4e00\u5b9a\u8981\u6709\u4e3b\u952e\uff0c\u9ed8\u8ba4\u4e3a`id`\uff0c\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u91cd\u65b0\u8bbe\u7f6e`_primary_key`\n* \u652f\u6301has_many\u548cbelongs_to\uff0c\u53ef\u4ee5\u5728\u5b50\u7c7b\u91cc\u5b9a\u4e49`_has_many`\u548c`_belongs_to`\n* \u6ca1\u6709`join`\u65b9\u6cd5\n\n# ChangeLog\n\n## 0.3.3\n* \u4fee\u590d\u65e0\u6cd5\u4ecepip\u5b89\u88c5\u7684bug\n* \u4fee\u590d\u5b89\u88c5\u65f6\u5bf9redis-py\u7684\u4f9d\u8d56\n* `import thing`\u53d8\u4e3a`from thing import thing`\n\n## 0.3.2\n* \u4fee\u590d\u4e86\u5e76\u53d1\u60c5\u51b5\u4e0b\u4f1a\u51fa\u73b0\u300cException _mysql_exceptions.ProgrammingError: (2014, \"Commands out of sync; you can't run this command now\"\u300d\u9519\u8bef\u3002\n* Redis\u7f13\u5b58\u53d8\u4e3a\u53ef\u914d\u7f6e\u9879\u3002\u5982\u679c\u4e0d\u60f3\u8981Redis\u7684\u8bdd\uff0c\u5728config\u91cc\u53d6\u6d88`Redis`\u914d\u7f6e\u5373\u53ef\u3002\n\n## 0.3.1\n* \u53d6\u6d88\u4e86\u5bf9Validation\u7684\u652f\u6301\n* \u53d6\u6d88\u4e86\u5bf9Sharding\u548cPartition\u7684\u652f\u6301\n* \u53d6\u6d88\u4e86\u4e8b\u4ef6\u5206\u53d1\u673a\u5236", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/lzyy/thing", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "thing", "package_url": "https://pypi.org/project/thing/", "platform": "any", "project_url": "https://pypi.org/project/thing/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/lzyy/thing" }, "release_url": "https://pypi.org/project/thing/0.3.3/", "requires_dist": null, "requires_python": null, "summary": "lightweight SQLAlchemy based ORM", "version": "0.3.3" }, "last_serial": 800558, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "27a8ea0c67f347e83fedbb5ebbd13f33", "sha256": "ceed47e9c0818acac372db5eb96b7c5697d1f1dade0c02f079a68b1ebbacc9d5" }, "downloads": -1, "filename": "thing-0.2.tar.gz", "has_sig": false, "md5_digest": "27a8ea0c67f347e83fedbb5ebbd13f33", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5230, "upload_time": "2012-05-09T07:22:34", "url": "https://files.pythonhosted.org/packages/40/3b/a98509fd9076470dde92f99f0accd361115f76ea8c6ef44d67f57b1c4d6e/thing-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "459c2a3b29f4dcc59b873484ef7361c2", "sha256": "7782d2c12c9a25d14ba93319f91f68c4f3a2ba0e55cad8ae1db5ccaa211fa777" }, "downloads": -1, "filename": "thing-0.2.1.tar.gz", "has_sig": false, "md5_digest": "459c2a3b29f4dcc59b873484ef7361c2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5226, "upload_time": "2012-05-13T08:37:36", "url": "https://files.pythonhosted.org/packages/16/f1/bc2447a39c992a3bc0f2feab6564665fd0ce868c860a44c14d893d426094/thing-0.2.1.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "812ef29e18f641853b2796978b427d87", "sha256": "e8c8535e728ad27f1fcbb785acd526b9a4e8bcc5e0ce9bca4f888b9fdcb2130a" }, "downloads": -1, "filename": "thing-0.3.0.macosx-10.8-intel.exe", "has_sig": false, "md5_digest": "812ef29e18f641853b2796978b427d87", "packagetype": "bdist_wininst", "python_version": "any", "requires_python": null, "size": 68033, "upload_time": "2013-04-15T16:08:37", "url": "https://files.pythonhosted.org/packages/a0/d1/a4405b057fc981634251697111d0a08da556a49c178210f079a9f5b2d87a/thing-0.3.0.macosx-10.8-intel.exe" }, { "comment_text": "", "digests": { "md5": "38255d46ad23156475abfeb17accaf25", "sha256": "e2befb0cfdd8844c8208297c79763b18b19035004b275b858f788f9f463c698e" }, "downloads": -1, "filename": "thing-0.3.0.tar.gz", "has_sig": false, "md5_digest": "38255d46ad23156475abfeb17accaf25", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5392, "upload_time": "2013-04-15T16:07:36", "url": "https://files.pythonhosted.org/packages/e7/20/e42d490b5747288650cdfe930ab8e0bf2d677ec53bb111da95dec86de34f/thing-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "80372b4e93585a0b540ecdf068805d03", "sha256": "ad4e2f73f293121b9439ec441c9e07002227dafbd7a8df992ca7f3bb7afc8ee7" }, "downloads": -1, "filename": "thing-0.3.1.macosx-10.8-intel.exe", "has_sig": false, "md5_digest": "80372b4e93585a0b540ecdf068805d03", "packagetype": "bdist_wininst", "python_version": "any", "requires_python": null, "size": 78810, "upload_time": "2013-04-15T16:16:44", "url": "https://files.pythonhosted.org/packages/df/fa/c84acec61a74b3d369dfeb09e95f38a14e2cf3555b5fcf1df5b1bf9fb66c/thing-0.3.1.macosx-10.8-intel.exe" }, { "comment_text": "", "digests": { "md5": "17e246e3f6ef1f702a25487d1c5059f4", "sha256": "b82365025f1744ce3ee5e3ef5717c9c4938708040843fd5ab0beadf602549632" }, "downloads": -1, "filename": "thing-0.3.1.tar.gz", "has_sig": false, "md5_digest": "17e246e3f6ef1f702a25487d1c5059f4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10742, "upload_time": "2013-04-15T16:16:25", "url": "https://files.pythonhosted.org/packages/7a/03/b17d3c1043aaa30c50d4fec71085db2d93580580acdd6ccbfc0bfafde1f1/thing-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "5e1bd1a998012d80266ebf76ed6fbcaa", "sha256": "c40e2bf5ab3026d1d41d5055bb9c915248e81d11a9b2c22339bf00279d0bb627" }, "downloads": -1, "filename": "thing-0.3.2.macosx-10.8-intel.exe", "has_sig": false, "md5_digest": "5e1bd1a998012d80266ebf76ed6fbcaa", "packagetype": "bdist_wininst", "python_version": "any", "requires_python": null, "size": 79500, "upload_time": "2013-04-29T00:57:09", "url": "https://files.pythonhosted.org/packages/9c/7a/4724bce674510fb31e41a9a8968c08b653618f88b42b48ab20184b8d710b/thing-0.3.2.macosx-10.8-intel.exe" }, { "comment_text": "", "digests": { "md5": "f05fa0707ce55bd5df5063f8c43fd721", "sha256": "a30568d153b6733a4b14c74e44616847017970e925832e5525363f25c58ddb81" }, "downloads": -1, "filename": "thing-0.3.2.tar.gz", "has_sig": false, "md5_digest": "f05fa0707ce55bd5df5063f8c43fd721", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11235, "upload_time": "2013-04-29T00:57:04", "url": "https://files.pythonhosted.org/packages/24/8b/71623780d4a27d7aac2549ffec030b635ea5ebf95ce57f841c822d25eca9/thing-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "d0dac0ccd9e67d8615aef133b4894406", "sha256": "232b192f5c116f0cdba9df657eed71796ad4cd93fbd8696fa346daa415ab3b87" }, "downloads": -1, "filename": "thing-0.3.3.tar.gz", "has_sig": false, "md5_digest": "d0dac0ccd9e67d8615aef133b4894406", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12065, "upload_time": "2013-05-02T09:16:39", "url": "https://files.pythonhosted.org/packages/51/37/1ba68e525a82e4a6f23ff56e4df6f7c2f94198924fa20356cdc04311cf10/thing-0.3.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d0dac0ccd9e67d8615aef133b4894406", "sha256": "232b192f5c116f0cdba9df657eed71796ad4cd93fbd8696fa346daa415ab3b87" }, "downloads": -1, "filename": "thing-0.3.3.tar.gz", "has_sig": false, "md5_digest": "d0dac0ccd9e67d8615aef133b4894406", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12065, "upload_time": "2013-05-02T09:16:39", "url": "https://files.pythonhosted.org/packages/51/37/1ba68e525a82e4a6f23ff56e4df6f7c2f94198924fa20356cdc04311cf10/thing-0.3.3.tar.gz" } ] }