我在SQLAlchemy中发现了一种意想不到的行为。我使用以下版本:
这是示例的表定义:
import asyncio
from aiopg.sa import create_engine
from sqlalchemy import (
MetaData,
Column,
Integer,
Table,
String,
)
metadata = MetaData()
users = Table('users', metadata,
Column('id_user', Integer, primary_key=True, nullable=False),
Column('name', String(20), unique=True),
Column('age', Integer, nullable=False, default=0),
)现在,如果我尝试对表执行一个简单的插入,只填充id_user和name,那么列age应该是自动生成的,对吗?让我们看看..。
@asyncio.coroutine
def go():
engine = yield from create_engine('postgresql://USER@localhost/DB')
data = {'id_user':1, 'name':'Jimmy' }
stmt = users.insert(values=data, inline=False)
with (yield from engine) as conn:
result = yield from conn.execute(stmt)
loop = asyncio.get_event_loop()
loop.run_until_complete(go())这是带有相应错误的结果语句:
INSERT INTO users (id_user, name, age) VALUES (1, 'Jimmy', null);
psycopg2.IntegrityError: null value in column "age" violates not-null constraint我没有提供age列,那么age = null值来自何处?我以为会发生这样的事情:
INSERT INTO users (id_user, name) VALUES (1, 'Jimmy');或者,如果默认标志确实有效,则应该是:
INSERT INTO users (id_user, name, Age) VALUES (1, 'Jimmy', 0);你能给这个放点光吗?
发布于 2015-03-06 20:20:10
此问题已被证实存在aiopg缺陷。现在,它似乎忽略了关于数据操作的default参数。
我已经使用server_default修复了这个问题:
users = Table('users', metadata,
Column('id_user', Integer, primary_key=True, nullable=False),
Column('name', String(20), unique=True),
Column('age', Integer, nullable=False, server_default='0'))发布于 2015-03-06 15:33:06
我认为您需要在插入中使用inline=True。这就关闭了“执行前”。对于这种“执行前”所包含的内容,Docs有点神秘,但它们提到了默认参数:
:param inline:
if True, SQL defaults present on :class:`.Column` objects via
the ``default`` keyword will be compiled 'inline' into the statement
and not pre-executed. This means that their values will not
be available in the dictionary returned from
:meth:`.ResultProxy.last_updated_params`.这段docstring来自Update类,但它们与Insert具有共享行为。
此外,这是他们测试它的唯一方法:insert.py#L385
https://stackoverflow.com/questions/28901050
复制相似问题