SQLAlchemy学习笔记1

1.在已有的数据库上建立model对象有两种办法。

 

   1> 先创建Table对象,然后创建要映射的object对象,用mapper将之映射起来。例子如下:

 

   department = Table('crew_section',
                      Column('rid',Integer,primary_key=True),
                       Column('birthdate', NormalDate),
                       Column('employmenttype',Integer,ForeignKey(department.c.rid)),
                    meta,autoload=True,autoload_with=engine)


class Department(object):
    def __repr__(self):
        return "<%s>"% repr(self.__class__.__name__)

mapper(Department, department)
    

 

crew_section是数据库中表的名字,在瘟到死下大小写不敏感,所以不用区分大小写,在os x下是则需要区分大小写。

 

用这种办法创建出来的映射对象,只重载明确表示出来的字段如代码中的‘birthdate’字段(做自定义的类型转换)、'employmenttype'字段(做映射的外键),其他未重载的字段可以直接以属性的形式倍调用如 department.other.

 

2>直接继承自DeclarativeBase:

 

class CrewBase(DeclarativeBase):
    __tablename__ ='crew_base'
    
    #{ Attributes
    id = Column('rid', Integer, primary_key=True)
    name = Column('crewbasecode', PopularString)
    description = Column('description', Text)
    #}
    
    def __repr__(self):
        return " <Base code:%s ,description:%s>"  % (self.code, self.description)

  crew_base 是数据库的表名。

  这样做必须对所有的字段重载,否则其他的属性不能被调用。

  对于已有的数据库,建议使用这种办法,这样可以清楚表明对象的设计结构。而且可以将建好的数据库字段名改为自己认为比较合适的。(个人项目比较特殊)

 

2 一对多的操作(基于继承自 DeclarativeBase的办法)

 

department_id = Column('employmenttype', Integer, ForeignKey(Department.id))  
department = relation(Department, backref=backref('crew_member', order_by=Department.id))

 

    第一行代码将数据库中的字段以外键形式重载,第二行代码建立外键,外键映射对象,本对象之间的关系

 

   之后可以直接实例化对象。用instance.department来取出对象的department属性。

 

    crew_member => 本对象所映射的表名。

 

  这里 一个department具有多个crew 主动关联的一方在crew。

 

3. 多对多的操作。

 

    先将多对多关系的中间表建立Table对象:

 

 

crew_base_period = Table('crew_base_period', metadata,
                         Column('crewrid',Integer, ForeignKey('crew_member.rid')),
                         Column('crewbaserid', Integer, ForeignKey('crew_base.rid')),
                         Column('startdate', NormalDate),
                         Column('enddate', NormalDate)
                         )

 

 在主动关联的一方写下如下语句:

 

 

   bases = relation(CrewBase, secondary=crew_base_period, backref='crew_member') 

 

 CrewBase是要关联的对象,将中间表对象传给secondary参数,backref为自己的表。

 

  实例化之后就可以直接调用instance.bases来查找自己想要的属性。

 

4.自定义类型转型

 

 

class PopularString(types.TypeDecorator):
    "to remove some unuseful data and convert the decode it"
    
    impl = types.String
    
    def process_bind_param(self, value, dialect):
        return "PREFIX:" + value
    
    def process_result_value(self, value, dialect):
        return value.strip().decode('gbk')

 

    impl是要转化的值本来的类型,prosess_bind_param处理从程序到db的操作,prosess_bind_param处理从db到程序的操作。

 

   定义好之后,直接将类名写到定义Column的地方就好了。如:

 Column('birthdate', NormalDate)

 

   但是很奇怪的是,用自定义好的类型,用query.filter()查询,类型转换可以起作用。如果用from_statement发送sql就要用下面的办法。

 

 

typemap = {
           'lastname' : PopularString,
           'firstname' : PopularString,
           'birthdate' : NormalDate,
           'inservicedate' : NormalDate,
           'outservicedate': NormalDate,
           'upgradeddate' : NormalDate,
           'sex': PopularGender
                                }



crew = DBSession.query(Crew).from_statement(text("SELECT * from crew_member where "  +
                                                "rtrim(crew_member.lastname) || rtrim(crew_member.firstname) " +
                                                " like '%" + crew_name + "%'", typemap=typemap)).first()



 

 (再次说明,本人的项目很妖怪,其实不用写这么复杂,如果你不小心google到这里来了,希望不要误导了你)

 

   需要先格外的写个text,typemap中即为{‘字段名’:自定义类型}的字典。

 

5. 其他的一些小问题

 

   sqlalchemy可以直接这样操作字段(以Crew为对象)

 

 

        crew = DBSession.query(Crew).filter((Crew.last_name + Crew.first_name).like(u'%XX%'.encode('gbk'))).first()

 

  即使用 + 来代替数据库的连接符

 

 

   filter 和 from_statement 似乎有冲突,不能对同一条记录查询。

 

 

 6.一切框架都是浮云(by Hsu Jeffrey

 

    Jeffrey兄说得很对。。。最近两个星期研究sqlalchemy看来,不管是怎么样的操作,其实归根到底,依旧是化为sql来对数据库操作。所以还是得好好研究研究底层点的东西。

 

  附件为例子,包含本文大部分的例子。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值