pony.orm基础入门

什么是Pony ORM

Pony是一个高级的对象关系映射器。ORM允许开发人员以对象的形式来处理数据库的内容。一个关系型数据库包含的是存储在表中的行。然而,当用高级的面向对象语言编写程序时,当从数据库中检索的数据可以以对象的形式访问时,就会方便很多。Pony ORM是Python语言的一个库,可以方便地处理以行形式存储在关系型数据库中的对象。

  • 优点
    编写查询的语法特别方便
    自动查询优化
    自动创建数据表

安装

pip install pony

导入

from pony.orm import *

这将导入使用Pony所需的整个(而不是非常大)的类和函数集。最终您可以选择要导入的内容,但我们建议您首先使用import * ,或者仅导入所需:

from pony.orm import (Json, PrimaryKey, Required, db_session, select, desc, Set, get, Optional, Database)

创建数据库对象

  • 方法一、创建空的数据连接然后绑定

db = Database()
空的连接往往是更方便做后期使用DB()方法。这样你就可以使用不同的数据库进行测试和制作。
然后进行绑定,支持多种数据库db.bind()
postgres:db.bind('postgres', user='', password='', host='', database='')
mysql:db.bind('mysql', host='', user='', passwd='', db='')
oracle:db.bind('oracle', 'user/password@dsn')
sqlite:db.bind('sqlite', 'filename', create_db=True) create_db:如果数据库不存在创建数据库文件

  • 方法二、通过参数连接

db = Database("mysql", host="localhost",
user="root",
passwd="123123",
db="t2")
代码示例

from pony.orm import Database
import os
import logging
from pony.orm import (Json, PrimaryKey, Required, db_session, select, desc, Set, get, Optional)
'''
Pony规定与数据库进行交互的代码必须在数据库会话中工作
可以使用@db_session装修或db_session上下文管理数据库的工作。
当会话结束时,它会做以下操作
提交事务或则回滚事务。
返回连接池的数据库连接。
清除缓存。
'''
# logging.basicConfig(level=logging.DEBUG,format='%(asctime)s::%(message)s::%(levelname)s::%(args)s')

db = Database(provider = "mysql",
              host = os.getenv('HOST') if os.getenv('MY_HOST') else '10.1.1.1',
              port = int(os.getenv('Port')) or 3307,
              user = os.getenv('USER') if os.getenv('MY_USER') else 'root',
              password = os.getenv('PASSWORD') or '1256',
              database = os.getenv('DB') or 'message_center'
              )

定义实体

凡继承Database.Entity的类都是实体类,实体类实例存储在数据库中,该数据库绑定到db变量。
例:class Content(db.Entity)

属性

class Info(db.Entity):
    _table_ = 'info'
    id = PrimaryKey(int, auto = True) #autoBoolean 是否自增
    key = Required(str, 50)
    name = Required(str, 30, default = "未知") #如果是必须的话必须加默认值
    url = Optional(str, 100)
    comment = Optional(str, 50, nullable = True)
    create_time = Required(datetime.datetime, default = datetime.datetime.now(), nullable = True)
    update_time = Optional(datetime.datetime)
    type = Required(str, 50)
    isdelete = Optional(bool)

属性类型分:Required(必选)、Optional(可选)、PrimaryKey(主键)、Set

Set

定义了一对一,一对多,多对多等数据结构

classStudent(db.Entity):

    name = Required(str)

   courses =Set("Course")
classCourse(db.Entity):

    name=Required(str)

    semester =Required(int)

    students =Set(Student)

     PrimaryKey(name, semester)

属性数据类型

格式为:属性名 = 属性类型(数据类型)
str
unicode
int
float
Decimal
datetime
date
time
timedelta
bool
buffer - used for binary data in Python 2 and 3
bytes - used for binary data in Python 3
LongStr - used for large strings
LongUnicode - used for large strings
UUID

属性参数

字符串长度 默认为255
name = Required(str,40)# VARCHAR(40)
整数的大小 默认32bit INTEGER
attr1 = Required(int,size=8) #8bit - TINYINTinMySQL
attr5 = Required(int,size=64) #64bit - BIGINTinMySQL
无符号
attr1 = Required(int, size=8,unsigned=True)# TINYINT UNSIGNEDinMySQL
小数和精度
price = Required(Decimal,10,2)# DECIMAL(10, 2)
时间
dt = Required(datetime, 6)
其他的参数
unique
Boolean 是否唯一
auto
Boolean 是否自增
default
默认值
sql_default
created_at = Required(datetime, sql_default=’CURRENT_TIMESTAMP’)
index
index=True创建的默认索引名称
index=’index_name’指定索引名称.
reverse
Specifies the attribute at the other end which should be used for the relationship.
reverse_column
Used for a symmetric relationship in order to specify the name of the database column for the intermediate table.
reverse_columns
Used for a symmetric relationship if the entity has a composite primary key. Allows you to specify the name of the database columns for the intermediate table.
table
多对多中间表的表名
nullable
允许该列为数据库中的空

将实体映射到数据库表

创建表,实体类的映射关系,这种映射关系非常重要,pony在启动项目时会检查整个项目的所有实体类的映射关系是否正确。为此,我们需要在Database对象上调用generate_mapping()方法:

db.generate_mapping(create_tables=True)

import connexion
from database.mysql_conn import db
from database.db_info import Info
from database.db_content import Content


if __name__ == '__main__':

    db.generate_mapping(create_tables=True)  # 创建表,实体类的映射关系,这种映射关系非常重要,pony在启动项目时会检查整个项目的所有实体类的映射关系是否正确。

参数create_tables = True表示如果实体指向的表尚不存在,则使用CREATE TABLE命令创建它们。必须在调用generate_mapping()方法之前定义连接到数据库的所有实体。

注:仅调用一次,且调用的的py文件必须import全部实体的类,否则报错pony.orm.core.ERDiagramError: Cannot define entity 'Content': database mapping has already been generated

实例

每个实例对应于数据库表中的一行

Content(msgtype=msgtype, name=name, content=content, project=project, sprint=sprint, create_time=datetime.datetime.now(), isdelete=0)

会话

Pony规定与数据库进行交互的代码必须在数据库会话中工作可以使用@ db_session装修,当会话结束时,它会做以下操作:

  • 如果函数引发异常,则执行事务回滚
  • 如果数据已更改且未发生异常,则提交事务
  • 返回连接池的数据库连接
  • 清除数据库会话缓存
    @classmethod
    @db_session
    def db_create_content(cls, msgtype, name, content):
        obj = get(n for n in Content if n.name == name)
        if obj:
            raise IsExist(title='该名字的模版已经存在', detail=f'name为【{name}】的模版已经存在')
        else:
            Content(msgtype=msgtype, name=name, content=str(content), create_time=datetime.datetime.now(), isdelete=0)

查询

要对结果列表进行排序,可以使用Query.order_by()方法。如果只需要结果集的一部分,则可以使用切片运算符,与在Python列表上执行的操作完全相同。例如,如果要按名称对所有人进行排序并提取前两个对象,则可以这样做:

select(pforpinPerson).order_by(Person.name)
select(n for n in Content if n.isdelete==0)

获取对象

要通过主键获取对象,您需要在方括号中指定主键值:
p1 = Person[1]
print p1.name

    @classmethod
    @db_session
    def db_get_content(cls):
        objs = select(n for n in Content if n.isdelete==0)
        data = []
        for obj in objs:
            dict = {
                "name": obj.name,
                "content": obj.content,
                "msgtype": obj.msgtype,
                # "project": obj.project,
                # "sprint": obj.sprint
            }
            data.append(dict)
        return data

您可能会注意到没有向数据库发送任何查询。发生这种情况是因为此对象已存在于数据库会话高速缓存中。缓存减少了需要发送到数据库的请求数。

要通过其他属性检索对象,可以使用Entity.get()方法:
mary = Person.get(name='Mary')
在这种情况下,即使对象已经加载到缓存中,仍然必须将查询发送到数据库,因为name属性不是唯一键。仅当我们通过主键或唯一键查找对象时,才会使用数据库会话高速缓存。

你可能感兴趣的:(pony.orm基础入门)