SQLAlchemy初始化和创建连接

SQLAlchemy初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column
from sqlalchemy.types import String, Integer
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('postgresql://test@localhost:5432/test')
DBSession = sessionmaker(engine)
session = DBSession()

BaseModel = declarative_base()

class User(BaseModel):
__tablename__ = 'user'

id = Column(String, primary_key=True)
username = Column(String, index=True)

class Session(BaseModel):
__tablename__ = 'session'

id = Column(String, primary_key=True)
user = Column(String, index=True)
ip = Column(String)

query = session.query(Session, User.username).join(User, User.id == Session.user)
for i in query:
print dir(i)

SQLAlchemy创建连接

Engine

engine 的定义包含了三部分的内容:

  1. 具体数据库类型的实现
  2. 连接池
  3. 策略(即engine自己的实现)

所谓的数据库类型即是MYSQL , Postgresql , SQLite 这些不同的数据库.
一般创建 engine 是使用create_engine方法:

1
engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')

对于这个字符串, SQLAlchemy 提供了工具可用于处理它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-

from sqlalchemy import create_engine
from sqlalchemy.engine.url import make_url
from sqlalchemy.engine.url import URL

s = 'postgresql://test@localhost:5432/bbcustom'
url = make_url(s)
s = URL(drivername='postgresql', username='test', password="",host="localhost", port=5432, database="bbcustom")

engine = create_engine(url)
engine = create_engine(s)

print engine.execute('select id from "user"').fetchall()

create_engine 函数有很多的控制参数, 这个后面再详细说.

Engine的策略

create_engine的调用, 实际上会变成strategy.create的调用. 而strategy就是engine的实现细节. strategy可以在create_engine调用时通过strategy参数指定, 目前官方的支持有三种:

  1. plain, 默认的
  2. threadlocal, 连接是线程局部的
  3. mock, 所有的 SQL 语句的执行会使用指定的函数

mock 这个实现, 会把所有的 SQL 语句的执行交给指定的函数来做, 这个函数是由create_engineexecutor 参数指定:

1
2
3
4
5
6
7
def f(sql, *args, **kargs):
print sql, args, kargs

s = 'postgresql://test@localhost:5432/bbcustom'
engine = create_engine(s, strategy='mock', executor=f)

print engine.execute('select id from "user"')

各数据库实现

各数据库的实现在 SQLAlchemy 中分成了两个部分, 一是数据库的类型, 二是具体数据库中适配的客户端实现. 比如对于 Postgresql 的访问, 可以使用psycopg2, 也可以使用pg8000:

1
2
3
s = 'postgresql+psycopg2://test@localhost:5432/bbcustom'
s = 'postgresql+pg8000://test@localhost:5432/bbcustom'
engine = create_engine(s)

具体的适配工作, 是需要在代码中实现一个 Dialect 类来完成的. 官方的实现在 dialects 目录下.

获取具体的 Dialect 的行为, 则是前面提到的URL对象的get_dialect方法.create_engine时你单传一个字符串,SQLAlchemy自己也会使用make_url得到一个URL的实例).

连接池

SQLAlchemy 支持连接池, 在create_engine时添加相关参数即可使用.

  1. pool_size:连接数
  2. max_overflow:最多多几个连接
  3. pool_recycle:连接重置周期
  4. pool_timeout:连接超时时间

连接池效果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- coding: utf-8 -*-

from sqlalchemy import create_engine
from sqlalchemy.engine.url import make_url
from sqlalchemy.engine.url import URL

s = 'postgresql://test@localhost:5432/bbcustom'
engine = create_engine(s, pool_size=2, max_overflow=0)


from threading import Thread

def f():
print engine.execute('select pg_sleep(5)').fetchall()


p = []
for i in range(3):
p.append(Thread(target=f))

for t in p:
t.start()

连接池的实现, 在create_engine调用时也可以指定:

1
2
from sqlalchemy.pool import QueuePool
engine = create_engine('sqlite:///file.db', poolclass=QueuePool)

还有:

1
2
3
4
from sqlalchemy.pool import NullPool
engine = create_engine(
'postgresql+psycopg2://scott:tiger@localhost/test',
poolclass=NullPool)

或者仅仅是获取连接的方法:

1
2
3
4
5
6
7
8
9
import sqlalchemy.pool as pool
import psycopg2

def getconn():
c = psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
# do things with 'c' to set up
return c

engine = create_engine('postgresql+psycopg2://', creator=getconn)

连接池可以被单独使用:

1
2
3
4
5
6
7
8
9
10
11
12
import sqlalchemy.pool as pool
import psycopg2

def getconn():
c = psycopg2.connect(username='ed', host='127.0.0.1', dbname='test')
return c

mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)

conn = mypool.connect()
cursor = conn.cursor()
cursor.execute("select foo")

连接池可以被多个 engine 共享使用:

1
e = create_engine('postgresql://', pool=mypool)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值