它只是我,还是Sqlite3傻瓜? [英] Is it just me, or is Sqlite3 goofy?

查看:74
本文介绍了它只是我,还是Sqlite3傻瓜?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能只是我。我12年来一直只使用Access和SQL Server

,所以我很确定我的意见不算什么。


然而,我很期待Sqlite3。现在

gmpy已升级,我可以继续安装

Python 2.5。


所以我打开手册到13.13节,我找到了第一个如何使用Sqlite3的例子:


< code>

conn = sqlite3 .connect('':memory:'')


c = conn.cursor()


#创建表

c.execute(''''''创建表库存

(日期时间戳,trans varchar,符号varchar,

数字十进制,价格十进制)''' ''')


#插入一行数据

c.execute(""" insert into stocks

值(''2006-01-05'',''购买'',''RHAT'',100,35.14)"")

< / code>


看起来非常简单,但我被这个例子迷惑和迷惑

。这么多,所以我添加了一个查询,以确切地看到

发生了什么。


< code>

#added by me

c.execute(''select * from stocks'')

d = c.fetchone()

for t in d:

打印类型(t),t

< / code>


原始代码 - 这有什么问题图片?

< type''unicode''2006-01-05

< type''unicode''BUY

<输入''unicode''RHAT

< type''int''100

< type''flora''35.14


为什么日期以字符串形式返回? Aren不是内置的

转换器应该处理吗?是的,如果您启用了

detect_types。


添加了detect_types = sqlite3.PARSE_DECLTYPES


Traceback(最近一次通话) last):

文件C:\Python25 \sqlite_first_example.py,第30行,< module>

c.execute(''select *来自股票'')

文件C:\Python25 \lib\sqlite3 \dbapi2.py,第66行,

convert_timestamp
datepart,timepart = val.split("")

ValueError:需要多于1个值来解包


啊哈,那个解释了为什么他们没有启用。


这个失败了因为

- 插入的值是错误的格式?

- 和内置转换器不能分割它因为它没有空格吗?

它工作时是因为

- detect_types没有设置,所以转换器在查询时不会被调用?


是的,示例中的格式是datetime.date和字段类型

应该是[日期],而不是[时间戳]需要HH:MM:SS

才能使转换器正常工作(但仅限于detect_types

启用)。


如果插入了正确的格式,转换器就可以工作


< type''datetime.datetime''2006- 09-04 13:30:00

< type''unicode''BUY

< type''unodeode''RHAT

< type''int''100

< type''flora''35.14


或者,如果该字段被正确地转换为[date]而不是[时间戳]

它也会有效。


< type''datetime.date''2006-09-04

< type''unicode''BUY

< type''unodeode''RHAT

< type''int''100

< type''flora''35.14


啊,这现在部分解释了原始结果,因为detect_types

默认是关闭的,现场演员,不是本地人sqlite3类型

被忽略,数据被查询为TEXT。


< type''unicode''2006-09-04

< type''unicode''BUY

< type''unodeode''RHAT

< type''int''100

< type''flora''35.14


好​​的,下一期,他妈的是什么[varchar]和[decimal]?

它们当然不是Sqlite3本机类型。如果它们是用户定义的类型,那么转换器和适配器在哪里?

Sqlite3是否只是忽略了一个未注册的演员?

请注意,虽然数量和价格都被投射为[十进制]

,但他们查询为int和float。


另请注意它''显而易见的'来自第13.13页的查询示例

示例为FUBAR

- 日期是unicode字符串,而不是datetime.date类型

- 价格是二进制浮点数,而不是十进制数


< quote>

此示例使用迭代器形式:

Probably just me. I''ve only been using Access and SQL Server
for 12 years, so I''m sure my opinions don''t count for anything.

I was, nevertheless, looking forward to Sqlite3. And now
that gmpy has been upgraded, I can go ahead and install
Python 2.5.

So I open the manual to Section 13.13 where I find the first
example of how to use Sqlite3:

<code>
conn = sqlite3.connect('':memory:'')

c = conn.cursor()

# Create table
c.execute(''''''create table stocks
(date timestamp, trans varchar, symbol varchar,
qty decimal, price decimal)'''''')

# Insert a row of data
c.execute("""insert into stocks
values (''2006-01-05'',''BUY'',''RHAT'',100,35.14)""")
</code>

Seems pretty simple, yet I was befuddled and bewildered
by this example. So much so that I added a query to see exactly
what was going on.

<code>
# added by me
c.execute(''select * from stocks'')
d = c.fetchone()
for t in d:
print type(t),t
</code>

Original code - what''s wrong with this picture?
<type ''unicode''2006-01-05
<type ''unicode''BUY
<type ''unicode''RHAT
<type ''int''100
<type ''float''35.14

Why is the date returning as a string? Aren''t the built in
converters supposed to handle that? Yes, if you enable
detect_types.

Added detect_types=sqlite3.PARSE_DECLTYPES

Traceback (most recent call last):
File "C:\Python25\sqlite_first_example.py", line 30, in <module>
c.execute(''select * from stocks'')
File "C:\Python25\lib\sqlite3\dbapi2.py", line 66, in
convert_timestamp
datepart, timepart = val.split(" ")
ValueError: need more than 1 value to unpack

Aha, that explains why they weren''t enabled.

This failed because
- the value inserted was wrong format?
- and the builtin converter can''t split it cuz it has no spaces?
when it worked it was because
- detect_types was not set, so converter not invoked when queried?

Yes, the format in the example was datetime.date and the field type
should have been cast [date], not [timestamp] which needs HH:MM:SS
for the converter to work properly (but only if detect_types
enabled).

If a correct format was inserted, converter would have worked

<type ''datetime.datetime''2006-09-04 13:30:00
<type ''unicode''BUY
<type ''unicode''RHAT
<type ''int''100
<type ''float''35.14

Or, had the field been properly cast as [date] instead of [timestamp]
it would also have worked.

<type ''datetime.date''2006-09-04
<type ''unicode''BUY
<type ''unicode''RHAT
<type ''int''100
<type ''float''35.14

Ah, this now partly explains the original result, since detect_types
is off by default, the field cast, not being a native sqlite3 type
was ignored and the data queried back as TEXT.

<type ''unicode''2006-09-04
<type ''unicode''BUY
<type ''unicode''RHAT
<type ''int''100
<type ''float''35.14

Ok, next issue, what the fuck are [varchar] and [decimal]?
They are certainly not Sqlite3 native types. If they are
user defined types, where are the converters and adapters?
Does Sqlite3 simply ignore a cast that isn''t registered?

Note that although both qty and price were cast as [decimal]
they queried back as int and float.

Note also that it''s "obvious" from the query example on page 13.13
that the example is FUBAR
- the date is a unicode string, not a datetime.date type
- the price is binary floating point, not decimal

<quote>
This example uses the iterator form:


>> c = conn.cursor()
c.execute(''select * from stocks order by价格'')
适用于c中的行:
>>c = conn.cursor()
c.execute(''select * from stocks order by price'')
for row in c:



...打印行

...

(u''2006-01-05'',u''BUY'',u''RHAT'',100,35.140000000000001)

( u''2006-03-28'',u''BUY'',u''IBM'',1000,45.0)

(u''2006-04-06'',你''卖'',你''',500,53.0)

(u''2006-04-05'',u''BUY'','''MSOFT''' ,1000,72.0)

< / quote>


她我们有一个显然工作的例子,因为错误的原因是
。程序员的一个典型例子

谁认为*他知道它是如何工作的,因为他写了。

这种邋is在生产中不会持续5分钟

环境。


但是为什么Sqlite3使qty成为一个int并定价浮动?

很难说自进一步的例子在DOCS中,没有b $ b甚至懒得去投射场类型。我猜我应该猜猜这些东西是如何运作的。我能相信

默认设置将是我想要的吗?


哈!我可以用锤子相信宝宝吗?


首先,请注意13.13.3节中的脚本示例

< quote>

导入sqlite3

con = sqlite3.connect(":memory:")

cur = con.cursor()

cur.executescript("""

创建表人(

名字,

姓氏,

年龄

);


创建表格书(

title,

作者,

发表

);


插入书中(标题,作者,已发表)

价值(

''Dirk Gently'''的整体侦探机构

''Douglas Adams'',

1987

);

""")

< / quote>


包含不是一个而是两个语法错误!

之后的单引号代理机构缺失一字,因为该行的末尾应该是逗号
。似乎没有人真正尝试过这个例子。


这很容易修复。但我很好奇为什么字段

没有类型演员。在之前的崩溃和

之后,我知道这段代码从未经过测试,我不会认为它会起作用。最好添加一个查询以确保。


cur.execute(选择标题,作者,从书中发布)

d = cur.fetchall()

for i in d:print i

print


(你是Dirk Gently'的整体侦探机构,你们''道格拉斯亚当斯'',1987年)


好​​的,所以如果不是演员,那么这些字段必须是默认的(也可能是当

a强制转换为没有我已经定义了。


但请注意:无知(但不是愚蠢)是我送给你的礼物

进行故障排除。我尝试(错误地)插入另一条记录:


cur.execute("插入书籍(标题,作者,已发布)值(''Dirk

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 侦探社,你们是道格拉斯·亚当斯,1987年)

(你们是Dirk Gently'的整体侦探机构,你们是道格拉斯·亚当斯,你们是'1987年'')


呃......数据库怎么能为每条记录设置不同的字段类型?


简单,当表格没有强制转换时无论你插入什么内容,字段类型都是

。这就是默认必须如何工作,

每个记录都有一个独立于其他记录的数据结构!


哇。想想*必须造成的那种错误*


错误?


这是我的例子,创建一个笛卡尔积


< code>

import sqlite3

letters = [(2,),('''10'',) ,(''20'',),(200,)]

con = sqlite3.connect(":memory:")

con.text_factory = str

con.execute(" create table letter(c integer)")

con.executemany(" insert into letter(c)values(?)" ,字母)

打印''查询:'',

表示con.execute中的行(" select c from letter"):

打印行,

打印

打印

打印''排序:'',

for con in con .execute(" c by letter order from c c):

打印行[0],

打印

打印
print''Cartesian Product:'',

for con.execute(" select ac,bc,cc from letter as a letter

作为b,字母为c):

打印行[0] +行[1] +行[2],

< / code>


请注意,要插入的数据列表包含两个字符串和

整数。但由于该字段被正确地转换为[整数],Sqlite3

实际上在db中存储了整数。我们可以从

" order by返回记录。


查询:(2,)(10,)(20,)(200,)


排序:2 10 20 200


笛卡尔乘积:6 14 24 204 14 22 32 212 24 32 42 222 204 212

222 402 14 22 32 212 22 30 40 220 32 40 50 230 212 220 230 410 24

32 42 222 32 40 50 230 42 50 60 240 222 230 240 420 204 212 222

402 212 220 230 410 222 230 240 420 402 410 420 600


因为如果我将它们作为[文本]进行转换,排序顺序会发生变化(而且我的

笛卡尔乘积变为连接而不是求和)。


查询:(''''')(''''')('''''),'''''','''''',')

分类:10 2 20 200


笛卡尔积:222 2210 2220 22200 2102 21010 21020 210200

2202 22010 22020 220200 22002 220010 220020 2200200 1022 10210

10220 102200 10102 101010 101020 1010200 10202 102010 102020

1020200 102002 1020010 1020020 10200200 2022 20210 202 20 202200

20102 201010 201020 2010200 20202 202010 202020 2020200 202002

2020010 2020020 20200200 20022 200210 200220 2002200 200102

2001010 2001020 20010200 200202 2002010 2002020 20020200 2002002

20020010 20020020 200200200

但是如果我完全省略演员表,那么数据库将输入完全按照原样存储

插入,所以c字段包含

文本和整数对我的排序顺序造成严重破坏,使用where使得

记录不可查询导致我的Cartesian

产品崩溃。


查询:(2,)(''''')(''''') (200,)


分类:2 200 10 20


笛卡尔积:6


回溯(最近一次调用最后一次):

文件C:\Python25 \ user\sqlite_test2.py,第225行,< module>

print row [0] + row [1] + row [2],

TypeError:不支持的操作数类型+:''int''和''str''


是的,我知道,我之前听过。


这种行为是设计的。

这仍然是他妈的''傻瓜。

... print row
...
(u''2006-01-05'', u''BUY'', u''RHAT'', 100, 35.140000000000001)
(u''2006-03-28'', u''BUY'', u''IBM'', 1000, 45.0)
(u''2006-04-06'', u''SELL'', u''IBM'', 500, 53.0)
(u''2006-04-05'', u''BUY'', u''MSOFT'', 1000, 72.0)
</quote>

Here we have an example of things apparently working
for the wrong reason. A classic example of the programmer
who *thinks* he knows how it works because he wrote it.
This kind of sloppiness wouldn''t last 5 minutes in a production
environment.

But why did Sqlite3 make qty an int and price a float?
Hard to say since THE FURTHER EXAMPLES IN THE DOCS don''t
even bother to cast the field types. I guess I''m supposed
to guess how things are supposed to work. Can I trust that
default settings will be what I want?

Ha! Can I trust the baby with a hammer?

First, note that the script example in section 13.13.3

<quote>
import sqlite3

con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
create table person(
firstname,
lastname,
age
);

create table book(
title,
author,
published
);

insert into book(title, author, published)
values (
''Dirk Gently''''s Holistic Detective Agency
''Douglas Adams'',
1987
);
""")
</quote>

contains not one but TWO syntax errors! A single quote after
the word Agency is missing as is the comma that should be at
the end of that line. Seems that no one actually ever tried
this example.

That''s easily fixed. But I was curious about why the fields
don''t have type casts. After the previous debacle and
knowing that this code was never tested, I am not going to
assume it works. Better add a query to make sure.

cur.execute("select title, author, published from book")
d = cur.fetchall()
for i in d: print i
print

(u"Dirk Gently''s Holistic Detective Agency", u''Douglas Adams'', 1987)

Ok, so if not cast, the fields must default (and probably also when
a cast is made that hasn''t been defined).

But watch this: being clueless (but not stupid) is a gift I have
for troubleshooting. I tried (incorrectly) to insert another record:

cur.execute("insert into book(title, author, published) values (''Dirk
Gently''''s Holistic Detective Agency'',''Douglas Adams'',''1987'')")

(u"Dirk Gently''s Holistic Detective Agency", u''Douglas Adams'', 1987)
(u"Dirk Gently''s Holistic Detective Agency", u''Douglas Adams'', u''1987'')

Uhh...how can a database have a different field type for each record?

Simple, without a cast when the table is created, the field type is
whatever you insert into it. That''s how the default must work,
each record has a data structure independent of every other record!

Wow. Just think of the kind of bugs *that* must cause.

Bugs?

Here''s MY example, creating a Cartesian Product

<code>
import sqlite3
letters = [(2,),(''10'',),(''20'',),(200,)]
con = sqlite3.connect(":memory:")
con.text_factory = str
con.execute("create table letter(c integer)")
con.executemany("insert into letter(c) values (?)", letters)
print ''Queried: '',
for row in con.execute("select c from letter"):
print row,
print
print
print ''Sorted: '',
for row in con.execute("select c from letter order by c"):
print row[0],
print
print
print ''Cartesian Product: '',
for row in con.execute("select a.c, b.c, c.c from letter as a, letter
as b, letter as c"):
print row[0]+row[1]+row[2],
</code>

Note that the list of data to be inserted contains both strings and
ints. But because the field was correctly cast as [integer], Sqlite3
actually stored integers in the db. We can tell that from how the
"order by" returned the records.

Queried: (2,) (10,) (20,) (200,)

Sorted: 2 10 20 200

Cartesian Product: 6 14 24 204 14 22 32 212 24 32 42 222 204 212
222 402 14 22 32 212 22 30 40 220 32 40 50 230 212 220 230 410 24
32 42 222 32 40 50 230 42 50 60 240 222 230 240 420 204 212 222
402 212 220 230 410 222 230 240 420 402 410 420 600

Because if I cast them as [text] the sort order changes (and my
Cartesian Product becomes concatenation instead of summation).

Queried: (''2'',) (''10'',) (''20'',) (''200'',)

Sorted: 10 2 20 200

Cartesian Product: 222 2210 2220 22200 2102 21010 21020 210200
2202 22010 22020 220200 22002 220010 220020 2200200 1022 10210
10220 102200 10102 101010 101020 1010200 10202 102010 102020
1020200 102002 1020010 1020020 10200200 2022 20210 20220 202200
20102 201010 201020 2010200 20202 202010 202020 2020200 202002
2020010 2020020 20200200 20022 200210 200220 2002200 200102
2001010 2001020 20010200 200202 2002010 2002020 20020200 2002002
20020010 20020020 200200200

But if I omit the cast altogether, then the db stores the input
exactly as it was inserted, so the c field contains both
text and integers wreaking havoc with my sort order, making
records un-queryable using "where" and causing my Cartesian
Product to crash.

Queried: (2,) (''10'',) (''20'',) (200,)

Sorted: 2 200 10 20

Cartesian Product: 6

Traceback (most recent call last):
File "C:\Python25\user\sqlite_test2.py", line 225, in <module>
print row[0]+row[1]+row[2],
TypeError: unsupported operand type(s) for +: ''int'' and ''str''

Yeah, I know, I''ve heard it before.

"This behavior is by design."

It''s still fuckin'' goofy.

推荐答案

在< 11 ****** ****************@p79g2000cwp.googlegroups .com> ;,
me********@aol.com 写道:
In <11**********************@p79g2000cwp.googlegroups .com>,
me********@aol.com wrote:

但请注意:无能为力(但不是愚蠢)是礼物我有

f或故障排除。我尝试(错误地)插入另一条记录:


cur.execute("插入书籍(标题,作者,已发布)值(''Dirk

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 侦探社,你们是道格拉斯·亚当斯,1987年)

(你们是Dirk Gently'的整体侦探机构,你们是道格拉斯·亚当斯,你们是'1987年'')


呃......数据库怎么能为每条记录设置不同的字段类型?


简单,当表格没有强制转换时无论你插入什么内容,字段类型都是

。这就是默认必须如何工作,

每个记录都有一个独立于其他记录的数据结构!


哇。想想*必须造成的那种错误*


错误?
But watch this: being clueless (but not stupid) is a gift I have
for troubleshooting. I tried (incorrectly) to insert another record:

cur.execute("insert into book(title, author, published) values (''Dirk
Gently''''s Holistic Detective Agency'',''Douglas Adams'',''1987'')")

(u"Dirk Gently''s Holistic Detective Agency", u''Douglas Adams'', 1987)
(u"Dirk Gently''s Holistic Detective Agency", u''Douglas Adams'', u''1987'')

Uhh...how can a database have a different field type for each record?

Simple, without a cast when the table is created, the field type is
whatever you insert into it. That''s how the default must work,
each record has a data structure independent of every other record!

Wow. Just think of the kind of bugs *that* must cause.

Bugs?



这不是一个错误,它是一个功能。并在常见问题解答中作为第三点回答:

http ://www.sqlite.org/faq.html#q3


我认为您的整体体验都是以此为基础的。与它一起生活或使用

真正的RDBMS。


如果你喜欢静态类型,为什么你在第一次使用Python呢

的地方?只需将其视为一致性 - 动态类型语言a ??

动态类型的DB列。 ;-)


Ciao,

Marc''BlackJack''Rintsch

It''s not a bug, it''s a feature. And answered as third point in the FAQ:

http://www.sqlite.org/faq.html#q3

I think your whole experience is based on it. Live with it or use a
real RDBMS.

If you are so fond of static typing, why are you using Python in the first
place? Just see it as consistency -- dynamically typed language a??
dynamically typed DB columns. ;-)

Ciao,
Marc ''BlackJack'' Rintsch


我******** @ aol.com 写道:

可能只是我。我12年来一直只使用Access和SQL Server

,所以我很确定我的意见不算任何东西。
Probably just me. I''ve only been using Access and SQL Server
for 12 years, so I''m sure my opinions don''t count for anything.



[...]

[...]


>

好​​的,接下来问题,他妈的是[varchar]和[decimal]?
>
Ok, next issue, what the fuck are [varchar] and [decimal]?



[..]

[..]


>

这是'仍然他妈的''高飞。
>
It''s still fuckin'' goofy.



语言......


问候

Steve

-

Steve Holden +44 150 684 7255 +1 800 494 3119

Holden Web LLC / Ltd http://www.holdenweb.com

Skype:holdenweb http://holdenweb.blogspot.com

最近的Ramblings http://del.icio.us/steve.holden

Language ...

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

< br>

me********@aol.com 写道:

可能只是我。我12年来一直只使用Access和SQL Server

,所以我很确定我的意见不算什么。
Probably just me. I''ve only been using Access and SQL Server
for 12 years, so I''m sure my opinions don''t count for anything.



SQLite从来没有假装成为一个成熟的RDBMS - 只是一个轻量级的简单嵌入式数据库,尽可能符合SQL标准。在它的类别中,

它胜过Access和MySQL。现在如果你想要一个真正的RDBMS,

你就没有选择合适的工具。我可以建议PostgreSQL吗?


(剪断无用的咆哮)


-

bruno desthuilliers

python -c" print''@''。join([''。''。join([w [:: - 1] for p in p.split(''。'')])对于''o **** @ xiludom.gro''中的
p.split(''@'')])"

SQLite never pretended to be a full-blown RDBMS - just a lightweight
simple embedded database as SQL-compliant as possible. In it''s category,
it beats Access and MySQL hands down. Now if you want a real RDBMS,
you''ve just failed to choose the right tool. May I suggest PostgreSQL ?

(snip useless rant)

--
bruno desthuilliers
python -c "print ''@''.join([''.''.join([w[::-1] for w in p.split(''.'')]) for
p in ''o****@xiludom.gro''.split(''@'')])"


这篇关于它只是我,还是Sqlite3傻瓜?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆