atom对象的数据库抽象层

atom-db的Python项目详细描述


Build Statuscodecov

Atom DB是 atom框架。这个包提供了 从基于json的文档数据库无缝保存和恢复atom对象 以及(即将推出)sqlalchemy支持的sql数据库。

为什么?

构建此数据库的主要原因是为了简化数据库集成 使用enaml应用程序。没有这个, 需要一个单独的框架来定义数据库模型,它是 重复工作。

这原本是enaml-web的一部分 但已被单独打包。

结构

这个设计有点基于django。使用Model.objects检索 用于创建查询的对象类型的管理器。不 对使用哪种类型的管理器进行了限制,将其留给 首选哪个数据库库(例如motor、txmongo、sqlalchemy…)。

除了Model.objects之外,序列化程序还作为 Model.serializer用于序列化和反序列化对象 到数据库和从数据库。

使用MongoDB和Motor

的示例

只需使用atom成员定义模型,但要对nosqlmodel进行子类化。

fromatom.apiimportUnicode,Int,Instance,Listfromatomdb.nosqlimportNoSQLModel,NoSQLModelManagerfrommotor.motor_asyncioimportAsyncIOMotorClient# Set DBclient=AsyncIOMotorClient()mgr=NoSQLModelManager.instance()mgr.database=client.test_dbclassGroup(NoSQLModel):name=Unicode()classUser(NoSQLModel):name=Unicode()age=Int()groups=List(Group)

然后我们可以创建一个实例并保存它。它将执行upsert或replace 现有条目。

admins=Group(name="Admins")awaitadmins.save()# It will save admins using it's ObjectIDbob=User(name="Bob",age=32,groups=[admins])awaitbob.save()tom=User(name="Tom",age=34,groups=[admins])awaittom.save()

要从数据库中获取数据,每个模型都有一个名为ModelManagerobjects的 只需返回模型类型的集合。例如。

# Fetch from db, you can use any MongoDB queries herestate=awaitUser.objects.find_one({'name':"James"})ifstate:james=awaitUser.restore(state)# etc...

还原是异步的,因为它将自动获取任何相关对象 (不包括本例中的组)。它在存在时使用objectid保存对象。

最后,您可以直接使用管理器上的查询删除,或者 调用对象。

awaittom.delete()assertnotawaitUser.objects.find_one({'name':"Tom"})

通过标记成员,可以将其从保存到数据库中排除 用.tag(store=False)

带aiomysql/aiopg的sql

只需使用atom成员定义模型,但要对sqlmodel进行子类化。

使用sqlalchemy表所需的信息标记成员,例如 Str().tag(length=40)将生成一个sa.String(40)。 见https://docs.sqlalchemy.org/en/latest/core/type_basics.html。标记 store=False将使该成员从数据库中排除。

atomdb将尝试确定正确的列类型,但如果需要更多 控件,可以标记成员以指定列类型。 type=sa.<type>或使用 column=sa.Column(...)。有关示例,请参见测试。

可以用primary_key=True标记成员,使其成为pk。Atomdb将 查找这些并将其分配给类的__pk__。如果未指定 它将创建并使用_id作为主键。如果指定了其他成员 作为主键,_id成员将被重新定义为实际主键的别名。

通过设置__model__ = "<table name>",可以通过 默认情况下,它使用类的fqdn。

DB发动机

在访问数据库之前,必须将“数据库引擎”分配给管理器 这样地。

importrefromaiomysql.saimportcreate_enginefromatomdb.sqlimportSQLModelManager# Parse the DB urlm=re.match(r'mysql://(.+):(.*)@(.+):(\d+)/(.+)',DATABASE_URL)user,pwd,host,port,db=m.groups()# Create the engineengine=awaitcreate_engine(db=db,user=user,password=pwd,host=host,port=port)# Assign it to the managermgr=SQLModelManager.instance()mgr.database=engine

然后,管理器将使用它来执行查询。

表格创建/删除

将表定义为Atom模型后,使用 sqlalchemy引擎上的异步包装器。

fromatomdb.sqlimportSQLModel,SQLModelManager# Call create_tables to create sqlalchemy tables. This does NOT write them to# the db but ensures that all ForeignKey relations are createdSQLModelManager.instance().create_tables()# Now actually drop/create for each of your models# Drop the table for this model (will raise sqlalchemy's error if it doesn't exist)awaitUser.objects.drop()# Create the user tableawaitUser.objects.create()

类似orm的查询

只有非常基本的orm风格的查询才被实现用于常见的用例。这些 分别是getget_or_createfilterall。这些都接受 “django样式”查询使用<name>=<value><name>__<op>=<value>

例如:

john,created=awaitUser.objects.get_or_create(name="John Doe",email="jon@example.com",age=21,active=True)assertcreatedjane,created=awaitUser.objects.get_or_create(name="Jane Doe",email="jane@example.com",age=48,active=False,rating=10.0)assertcreated# Startswithu=awaitUser.objects.get(name__startswith="John")assertu.name==john.name# In queryusers=awaitUser.objects.filter(name__in=[john.name,jane.name])assertlen(users)==2# Is queryusers=awaitUser.objects.filter(active__is=False)assertlen(users)==1andusers[0].active==False

sqlachemy's ColumnElement 可以用这种方式使用的查询。测试还检查这些 实际按计划工作。

高级/原始查询

使用连接等进行更高级的查询。必须使用 然后执行sqlalchemy。可以检索原子模型的sa.Table 使用Model.objects.table可以在其上使用select、where等…建造 提出你需要的任何问题。

然后使用fetchallfetchonefetchmanyexecute进行查询。

这些方法不返回对象,而是返回数据库,所以他们 必须手动还原。

加入时,您通常希望通过use_labels=True。例如:

q=Job.objects.table.join(JobRole.objects.table).select(use_labels=True)forrowinawaitJob.objects.fetchall(q):# Restore each manually, it handles pulling out the fields that are it's ownjob=awaitJob.restore(row)role=awaitJobRole.restore(row)

根据这些关系,您可能需要对它们进行后期处理,以便 可以用更像Python的方式访问。这是复杂的权衡。 使用方便。

贡献

这是早期的发展,可能有问题。拉取请求, 功能要求,欢迎!

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
用户界面java,使用gui连接到另一台计算机/服务器的文件系统   运行sbt的ubuntu返回错误:“javahome需要<path>参数”   java如何在Android中处理许多ImageView而不出现内存问题?   查询中非法字符的java相同URL失败   安卓取消引用可能会产生“java”。lang.NullPointerException'   java中的indexoutofboundsexception“java.lang.ArrayIndexOutOfBoundsException”错误   xml Java将dom保存到文件>文件在程序结束后由另一个进程打开   Java的垃圾收集器是如何工作的?   Java如何筛选值(列表)   java处理字符串我怎样才能像在真实的书籍中一样在上面部分生成“小数字”呢?   java SonarQube是否有一个API来获取所有项目分析的一部分?   java startActivity(intent)什么都不做   JAVAutil。扫描器类Java   java如何从Firebase更新电子邮件?UpdateMail方法已被弃用   java Hibernate。如何正确组织带有注释的onetomany关系?   在java中获得卷标和驱动器号之间的映射(而不是FileSystemView)的解决方法是什么   java查找文件的路径