相信科德还是您的设施?

无头痛的存储对象:在ObjectScript和Python中使用Caché对象的简单示例



新天鹅堡

到2020年6月,正好有50年的表格数据仓库或正式的关系数据模型。 这是正式文件- 相同的著名文章 。 为此,我们要感谢Edgar Frank Codd博士。 而且,顺便说一下,关系数据模型在《福布斯》最近100年最重要的全球创新中名列前茅。

另一方面,奇怪的是,科德认为关系数据库和SQL语言是其理论的一种失真的实现。 作为指导,他甚至制定了每个关系数据库管理系统都必须满足的12条规则(实际上,这是13条规则)。 而且,实际上,今天,在世界上,您找不到至少满足Codd的“规则0”的DBMS,因此,没有人可以称其DBMS为100%关系型:)也许有例外,告诉我吗?

关系模型不是很复杂,并且一直在研究。 甚至可能对其进行过深入的研究。 同时,在2019年这一年,我们还将庆祝另一个周年纪念日-恰好在10年前,后来“不仅SQL”上的#NoSQL主题标签出现在Twitter上,并开始迅速渗透到开发数据库模型的实践中。

为什么这么长的介绍? 而且,编程领域由数据(当然还有算法)组成,关系模型的垄断地位(更礼貌地说)导致了程序员的意识分裂。 因为开发人员头脑中的工作对象(OOP也是总数,对吗?),所以所有这些列表,队列,树,堆,字典,线程等都不是表。

如果您继续并记得现代DBMS中的存储体系结构? 我们直接说,没有人会以表格的形式存储数据。 DBMS开发人员最经常使用各种B树(例如,在PostrgeSQL中),或者较少使用基于字典的存储。 另一方面,使用DBMS进行存储的开发人员也会在非表上运行。 这迫使程序员不断缩小笨拙的中间数据层的语义鸿沟。 从而导致内部二分紧张,全身不适并消除失眠。

简而言之,存在一个矛盾-我们将数据打包到适合该任务的对象中,并且在保存数据时应注意一些表。

绝望? 否:)但是对象关系映射呢,在ORM的普通人中呢? 让我们与同志们将这场神圣的战争留给叶戈尔·布加坚科按照鲍勃叔叔的说法,上个世纪的整个故事不应该让我们担心

当然,值得一提的是,“带有字节的包”(罗伯特·马丁(Robert Martin)“纯体系结构”)可以序列化并放入文件中,或推入其他合适的流中。 但是,首先,它将立即限制我们的语言使用;其次,现在,我们将只担心存储在DBMS中。

使用字节袋进行的这些起起伏伏是一个令人愉悦的例外-IntersystemsCachéDBMS(现在是InterSystems IRIS数据平台)。 这可能是世界上唯一一个不会向开发人员隐瞒甚至走得更远的DBMS,它使人们无需思考“如何正确存储它”。 可以说该类延续了Persistent属,并且重点在帽子里, 也就是说,在全局变量中 (不要与全局变量混淆!)。

可以存储所有类型的数据,包括字符流和二进制流。 这是一个简单的示例:

//       - // :      ,     ,     , ,   Class FW.Events Extends %Persistent { Property "My name" As %String; } //      //   «»  set haJS = ##class(FW.Events).%New() //   write haJS.%Id() 

此外,这很棒,您不仅可以与Caché固有的ObjectScript中的存储对象进行通信,而且还可以直接在Python,Java,JavaScript,C ++,C#,Perl中检索和存储它们,并与它们进行通信。 甚至,哦,恐怖:)。 也可以通过SQL查询直接从相同的对象获取信息,还可以在对象上调用自己的方法。 更精确地讲,这种情况下的方法本身(和神奇的词SqlProc)变成了存储过程。 CachéDBMS已经掩盖了所有魔力。
如何获得对IntersystemsCachéDBMS的免费测试访问权?
不管邪恶的语言怎么说,这都是绝对真实的! :)您可以在此处下载并安装Caché的单用户全功能版本(您需要免费注册)。 适用于MacOS,Windows和Linux的版本。
使用基于Eclipse的Atelier IDE,使用ObjectScript代码并直接直接访问CachéDBMS服务器(以及InterSystems IRIS平台)最方便。 所有下载和安装说明均在此处

对于谁更方便和熟悉,可以使用舒适简单的Visual Studio Code,并通过社区开发的ObjectScript插件对其进行补充。

现在有一些实际的例子。 让我们尝试创建几个相关的对象,并在ObjectScript和Python中使用它们。 与其他语言的集成非常相似地实现。 选择Python是出于与ObjectScript的“最大亲和力”的原因-两种语言均可编写脚本,支持OOP且不具有强类型:)

对于示例的想法,我们转向“坐下来聚会框架”的蓬勃发展的哈巴罗夫斯克项目(不要与哈勃罗夫斯克混淆!)。 意识形态的源代码位于github.com/Hajsru/framework-weekend ,我们的源代码在文本中较低。
macOS用户的重要细微差别。 启动Python支持模块时,需要记住,需要指定DYLD_LIBRARY_PATH到安装Caché的目录的路径。 例如,像这样:
导出DYLD_LIBRARY_PATH = /应用程序/缓存/ bin:$ DYLD_LIBRARY_PATH
这在文档中有特别说明

我们在ObjectScript上创建存储的类


所以走吧 Caché的课程非常简单。 您可以在没有IDE的情况下进行操作-直接通过Caché平台实例的门户复制类代码(是的,CachéDBMS远不只是DBMS):系统浏览器>类>导入(名称空间USER)。

保存后,对象将显示在地球仪中,其名称与相应类的名称匹配。 还可以在Caché管理门户中查看:“系统浏览器”>“全局”(名称空间USER)。

 //    , ,      Class FW.Event Extends %Persistent { Property title as %String; Property description as %String; Property date as %Date; Property visitors as list of FW.Attendee; } //    / Class FW.Attendee Extends %Persistent { Property name As %String; } 

从Python访问Caché中的对象


首先,连接到CachéDBMS数据库。 我们按照文档中的内容进行重复。
只是一个有用的事实。 它是免费的,也是CachéDBMS的培训版本,它将使您能够执行功能齐全的版本中的所有操作,但只允许两个活动连接。 因此,与此同时,将无法保持与IDE的连接并尝试运行其他代码来与服务器交互。 找到的最简单的解决方案是在运行Python代码时关闭IDE。
 #   Caché    Python3 import intersys.pythonbind3 #    conn = intersys.pythonbind3.connection() conn.connect_now("localhost[1972]:USER","_SYSTEM","SYS", None) #    print ("conn = %d " % conn.handle) #     database = intersys.pythonbind3.database(conn) 

现在,我们将创建一个IT事件及其参与者的对象数据库。 非常非常简单。 第一个是创建一个用于注册和存储有关事件参与者的信息的类。 为了简化类,仅提供成员名称。

 #         class Attendee: #        def __init__ (self): self.att = database.create_new("FW.Attendee", None) #             id def new (self, name): self.att.set("name", name) self.att.run_obj_method("%Save",[]) #    id     def use (self, id): self.att = database.openid("FW.Attendee",str(id),-1,-1) #       def clean (self): id = self.att.run_obj_method("%Id",[]) self.att.run_obj_method("%DeleteId", [id]) 

如您所见,我们使用现成的包装器函数来访问Caché:set中对象的字段的方法,并在参数中将属性名称用引号和openid传递,并带有包和类的名称。 关于类似的get函数,下面有一些示例。 要访问任何其他方法,包括该类从其祖先继承的方法,请在必要时将run_obj_method()函数与方法名称和调用参数一起使用。

该行中最重要的魔术:self.att.run_obj_method(“%Save”,[])
这样,我们便可以直接引用保存对象,而无需使用其他库和框架(例如无处不在且难看的ORM)。

此外,鉴于ObjectScript的面向对象性质以及其类的方法(在我们的示例中,我们没有这样做),我们可以从Python访问从Persistent类及其祖先继承的整个方法集中获得收益。 如果是的话, 这是完整列表

创建第一个成员:

 att = Attendee() att.new("") 

运行此代码后,将在数据库中显示一个名为FW.AttendeeD的全局变量,以及刚刚保存的对象的内容,如屏幕截图所示:



保存后,该对象具有其自己的ID(编号为1)。 因此,您可以使用以下ID将其加载到我们的程序中:

 att = Attendee() att.use(1) print (att.att.get("name")) 

现在,再次知道id(如果需要),您可以从参与者数据库中删除该对象:

 att = Attendee() att.use(1) att.clean() 

运行此示例后,检查有关对象的记录应在全局中消失。 尽管下载的数据仍保留在对象的“内存中”,直到程序终止。

让我们进行下一步。 创建实际的事件记录。

 #        class Event: #        def __init__ (self): self.event = database.create_new("FW.Event", None) #            id def new (self, title, desc, date): self.event.set("title", title) self.event.set("description", desc) self.event.set("date", date) self.event.run_obj_method("%Save",[]) #    id    def use (self, id): self.event = database.openid("FW.Event",str(id),-1,-1) #       def addAttendee (self, att): eventAtt = self.event.get("visitors") eventAtt.run_obj_method("Insert", [att]) self.event.set("visitors", eventAtt) self.event.run_obj_method("%Save",[]) #      def clean (self): id = self.event.run_obj_method("%Id",[]) self.event.run_obj_method("%DeleteId", [id]) 

该类的结构与上述类成员的结构几乎相同。 最重要的是,出现了一种将参与者添加到此事件addAttendee(att)的参与者列表中的方法。

我们尝试创建有关新事件的对象记录并将其保存在数据库中:

 haJS = Event() haJS.new("haJS", " ", "2019-01-19") 

结果应该是这样的(请注意,日期会自动转换为ObjectScript格式,并在重新加载到Python对象中后,它将返回为原始格式):



仍然需要将参与者添加到事件中:

 #     haJS = Event() haJS.use(1) #    att = Attendee() att.new("") #      haJS.addAttendee(att.att) 

因此,这些示例表明,无需同时考虑数据模型及其表格存储方案。 您可以使用更明显的工具来完成任务。

在文档和InterSystems开发人员社区门户网站上,始终可以找到有关使用Python和其他语言连接和使用Caché的详细说明-该社区不少于5,000个成员。
帮助:InterSystemsCaché多模型DBMS始终是对象数据库的永久领导者


Source: https://habr.com/ru/post/zh-CN435612/


All Articles