Bigzhu's den

SQLAlchemy

bigzhu bigzhu

问题分列

我要用 1.2 版本的, 要加 pre 参数

pipenv install --pre SQLAlchemy

建立数据库连接

engine = create_engine("postgresql+psycopg2://scott:tiger@host/dbname")

Data Definition Language (DDL)

建立 model

可以看这里 https://docs.sqlalchemy.org/en/rel_1_1/orm/mapping_styles.html

数据类型可以看这里: http://docs.sqlalchemy.org/en/latest/core/type_basics.html

engine

engine 可以在执行操作时 bind, 在操作不同数据库的性况下:Base.metadata.create_all(engin)

也可以在定义 Class 时绑定

declarative_base(bind=engine)

混合继承

我所有的表都有 id, created_at, updated_at 三个字段, 如果都定义, 太傻了.

弄个 Base 类, 要继承自 declarative_base 和 AbstractConcreteBase

class Base(AbstractConcreteBase, declarative_base(bind=engine)):
    '''
    基类
    '''
    id = Column(Integer, primary_key=True)
    created_at = Column(DateTime, default=datetime.datetime.utcnow)  # 建立时间
    updated_at = Column(DateTime, default=datetime.datetime.utcnow)  # update 时间

子类加上 :

__mapper_args__ = {'polymorphic_identity': 'oauth_info_new', 'concrete': True}

这样这些 class 定义的 table 自功就连到那个 engin 的数据库了

但是这样弄下来, 比直接定义 id, created_at, updated_at 还麻烦, 可读性还不好, 不用了, 不用了! 直接定义吧, 还更灵活一些

create table

Base.__table__.create(checkfirst=True)

checkfirst=True 在建立前检查, 如果存在了, 避免又建立报错

drop table

Base.__table__.drop()

alter table

这里 说的很明白了, 官方没有直接改的

Data Manipulation Language (DML)

https://docs.sqlalchemy.org/en/rel_1_1/orm/tutorial.html#creating-a-session

session

要先建立 session

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()

query

for base in session.query(Base):
    print(base.id, base.created_at)

where

session.query(User).filter(User.name.like('%ed')).order_by(User.id)

what

session.query(model.Last.updated_at).filter(model.Last.user_id == user_id)

join

query.outerjoin(User.addresses)

insert

http://docs.sqlalchemy.org/en/rel_1_1/orm/tutorial.html#adding-and-updating-objects

base = Base(id=1)
session.add(base)
session.commit()
`http://docs.sqlalchemy.org/en/rel_1_1/orm/tutorial.html#adding-and-updating-objects``
带条件

### update
```python
session.query(User).filter_by(id=123).update({"name": u"Bob Marley"})

json 比较

    god = session.query(God).filter(
        getattr(God, type)['name'].astext == name).one_or_none()

delete

bigzhu
Everything is learnable