I can select a record in sqlitemanager (firefox plugin).Please see the attatchment of the selected record.The database is here , http://pan.baidu.com/s/1eQ04tlo .
You can download it and test the sql statement.
select capital.代码 as code,quote.close as close, quote.close*capital.股份总数/10000 as market_cap,
balance.负债合计/balance.资产总计 as debt_ratio,
profit.归属于母公司所有者的净利润/balance.'所有者权益(或股东权益)合计' as roe,
profit.归属于母公司所有者的净利润/balance.'负债和所有者权益(或股东权益)总计' as roa ,
quote.close*capital.股份总数/profit.归属于母公司所有者的净利润 as pe,
quote.close*capital.股份总数/balance.资产总计 as pb
from profile,capital,quote,balance,profit
where capital.代码=300001
and profile.代码=capital.代码
and profile.代码=quote.code
and profile.代码=balance.代码
and profile.代码=profit.代码
and quote.date="20140523"
and balance.报告日期="20131231"
and profit.报告日期="20131231";
When i wrap it in python code ,i can't get the selected record,What is the matter?
# -*- coding: utf-8 -*-
import os,re,sqlite3
db_name='china.sqlite'
target_dir='e:\\workspace\\data\\'
con = sqlite3.connect(target_dir+db_name)
cur=con.cursor()
select_str='''select capital.代码 as code,quote.close as close, quote.close*capital.股份总数/10000 as market_cap,
balance.负债合计/balance.资产总计 as debt_ratio,
profit.归属于母公司所有者的净利润/balance.'所有者权益(或股东权益)合计' as roe,
profit.归属于母公司所有者的净利润/balance.'负债和所有者权益(或股东权益)总计' as roa ,
quote.close*capital.股份总数/profit.归属于母公司所有者的净利润 as pe,
quote.close*capital.股份总数/balance.资产总计 as pb
from profile,capital,quote,balance,profit
where capital.代码=300001
and profile.代码=capital.代码
and profile.代码=quote.code
and profile.代码=balance.代码
and profile.代码=profit.代码
and quote.date='20140523'
and balance.报告日期='20131231'
and profit.报告日期='20131231';'''
cur.execute(select_str)
print(cur.fetchall())
it's so strange for me to understand that that code1 can run,code2 can not run.
code1
import os,re,sqlite3
db_name='china.sqlite'
target_dir='e:\\workspace\\data\\'
con = sqlite3.connect(target_dir+db_name)
cur=con.cursor()
select_str='''select capital.代码 as code,quote.close as close, quote.close*capital.股份总数/10000 as market_cap,
balance.负债合计/balance.资产总计 as debt_ratio,
profit.归属于母公司所有者的净利润/balance.'所有者权益(或股东权益)合计' as roe,
profit.归属于母公司所有者的净利润/balance.'负债和所有者权益(或股东权益)总计' as roa ,
quote.close*capital.股份总数/profit.归属于母公司所有者的净利润 as pe,
quote.close*capital.股份总数/balance.资产总计 as pb
from profile,capital,quote,balance,profit
where capital.代码='300001'
and profile.代码='300001'
and quote.code='300001'
and balance.代码='300001'
and profit.代码='300001'
and quote.date='20140523'
and balance.报告日期='20131231'
and profit.报告日期='20131231';'''
cur.execute(select_str)
print(cur.fetchall())
code2
import os,re,sqlite3
db_name='china.sqlite'
target_dir='e:\\workspace\\data\\'
con = sqlite3.connect(target_dir+db_name)
cur=con.cursor()
select_str='''select capital.代码 as code,quote.close as close, quote.close*capital.股份总数/10000 as market_cap,
balance.负债合计/balance.资产总计 as debt_ratio,
profit.归属于母公司所有者的净利润/balance.'所有者权益(或股东权益)合计' as roe,
profit.归属于母公司所有者的净利润/balance.'负债和所有者权益(或股东权益)总计' as roa ,
quote.close*capital.股份总数/profit.归属于母公司所有者的净利润 as pe,
quote.close*capital.股份总数/balance.资产总计 as pb
from profile,capital,quote,balance,profit
where capital.代码=300001
and profile.代码=capital.代码
and profile.代码=quote.code
and profile.代码=balance.代码
and profile.代码=profit.代码
and quote.date='20140523'
and balance.报告日期='20131231'
and profit.报告日期='20131231';'''
cur.execute(select_str)
print(cur.fetchall())
In my point of view ,cod1 is equal to code2 logically ,there is no difference between them.
Is there difference between
where capital.代码='300001'
and profile.代码='300001'
and quote.code='300001'
and balance.代码='300001'
and profit.代码='300001'
and
where capital.代码=300001
and profile.代码=capital.代码
and profile.代码=quote.code
and profile.代码=balance.代码
and profile.代码=profit.代码
??
when i quote the code and get the right result ,so the reason of problem remain unknown.
I haven't downloaded the database since it's about 250 megabytes, and that's far too much to download to answer a simple question. If you want people to download the database, I suggest creating a small database with just a few records, the ones in your question.
Now for the actual answer: when you put quotes around the number 300001, you're searching for a string. When you omit the quotes, you're searching for an integer. The SQLite manual says that integers will never compare equal to strings (SQLite calls it a TEXT value):
An INTEGER or REAL value is less than any TEXT or BLOB value.
So your WHERE clause is never comparing equal when you search for an integer, because the actual value is a string. That's why you have to put quotes around "300001" is working.
UPDATE: The original version of my answer said "the actual value is an integer", which was backwards. After looking at the SQLite3 database that the OP posted, I see that the "代码" fields (for those who don't read Chinese, that translates roughly as "source code") are defined as TEXT fields in his schema. So I've edited my answer to swap integers and strings.
UPDATE 2: It seems, from the screenshots you've posted of sqlitemanager, that it is converting the integer values in your query to strings, because it knows that the SQL schema says that the 代码 field is a TEXT field and so it is correcting your query for you. (Which it should not do -- the number 1 is NOT the same as the string "1" and the one should NOT be converted into the other unless the user specifically asks for that conversion, but that's a rant about bad software design, which doesn't help answer your question.) So this "feature" of sqlitemanager (that's really a bug) is hiding the problem in your query, but the pysqlite3 library does not auto-convert data types and so it is exposing the problem.
Regardless of whether sqlitemanager's behavior is the right thing or not, the solution to your problem is very simple: make sure that when you're searching for a value in a TEXT field such as 代码, that you give it a search value that is a text string, enclosed in quotes. That will work everywhere, in both Python and in sqlitemanager, and so that's the way you want to write your queries.
Related
I'm using the click package to get input for one or more variables which get loaded in as a combined dictionary. Each entry is then joined and the combined string is added to the end of a base URL and sent through the requests package to receive some xml data.
Earlier I had an issue with one of the variables that let you search through a range, such as
[value1, value2]
Python added double quotes around it so the search function didn't operate correctly, so I used
.replace('"', '')
on the joined string before combined with the base url and that seemed to fix that problem. The issue now is that individual input that contains more than one word now doesn't produce the same output as the actual search engine online. I have to use quotes when I input the information to keep it as a single argument, but then the quotes get removed by the function above and I believe that is what is causing the issue.
I think if I have a way to access individual entries of this dictionary and remove the double quotes from only certain entries then that should get the job done. But if I am overlooking something please let me know.
Help is appreciated.
Code added below:
import click
import requests
#click.command()
#click.option(--variable1)
#click.option(--variable2)
query_list=[variable1, variable2]
query=''.join(query_list)
base_url = "abc.com...."
response=requests.get(base_url,query)
I'm writing code that takes a user-inputted string and binds it to a SQLite command through a parameter.
I've gotten this functionality to work when the string is already embedded in the query (see first example under "these lines do work"), and this binding method works with integers just fine (see second example).
testname = "\"EJtheDJ\"" #this would be user-inputted, but I get the same issue when I initialize it this way
#this line doesn't work
c.execute("select lastfm from usernames where discordname=?", (testname,))
#these lines do work
#c.execute("select lastfm from usernames where discordname=\"EJtheDJ\"")
#c.execute("select integer1 from test where integer2=?", (num,)) #num=3
print(c.fetchone()) #prints out "None"
My syntax seems 100% correct according to all the tutorials and forum threads I've looked at. I don't normally make posts here (in fact this is my first time), but I'm completely stumped on this and felt it was my only option. Any help would be massively appreciated. I'm running this on a CentOS server with Python 3.6, if that helps.
Edit: Turns out I just needed to do away with the escaped quotes. testname = EJtheDJ works perfectly.
I have the following sql query:
SELECT
pc.patente,
cs.cpc_group_codigo_cpc_group
FROM
patente_pc pc
,
patente_cpc cpc,
cpc_subgroup cs,
cpc_group cg
WHERE
pc.codigo_patente_pc = cpc.patente_pc_codigo_patente_pc AND
cpc.cpc = cs.codigo_cpc_subgroup AND
cs.cpc_group_codigo_cpc_group = cg.codigo_cpc_group
GROUP BY
pc.patente, cs.cpc_group_codigo_cpc_group
I add this query to python, separating line by line the string in a tuple to not have a problem with the syntax..
and it executes correctly
but when I need to retrieve the data, I use
lista_cpcs = []
lista_patentes = []
for (pc.patente, cs.cpc_group_codigo_cpc_group) in cursor:
lista_cpcs.append(cs.cpc_group_codigo_cpc_group)
lista_patentes.append(pc.patente)
return [lista_cpcs, lista_patentes]
and I get the error Global name 'pc' is not defined
I get whats happening, it's interpreting pc and cs as python modules, but they are from the sql..
how to work in this?
Ps: I search for python mysql connector and didn't found anything with this.
The variables in your for loop: (pc.patente, cs.cpc_group_codigo_cpc_group) are user defined; the names used do not have anything to do with the names from the query. Thus, you can call them whatever you want. You may consider using (pc__patente, cs__cpc_group_codigo_cpc_group) or something.
The problem is that the dot notation in python != the dot notation from your SQL.
Got it, sorry for the post..
Searching in https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-description.html
I learned a few attributes of the cursor, and using the Eclipse debugger I saw that it comes just the name, not the table connection..so I use
for (patente, cpc_group_codigo_cpc_group) in cursor:
lista_cpcs.append(cpc_group_codigo_cpc_group)
lista_patentes.append(patente)
and it's working now, and thanks for the help #Scott
Main problem:
I have a Python (3.4) Django (1.6) web app using an SQLite (3) database containing a table of authors. When I get the ordered list of authors some names with accented characters like ’Čapek’ and ’Örkény’ are the end of list instead of at (or directly after) section ’c’ and ’o’ of the list.
My 1st try:
SQLite can accept collation definitions. I searched for one that was made to order UTF-8 strings correctly for example Localized and Unicode collation in Android (Accented Search in sqlite (android)) but found none.
My 2nd try:I found an old closed Django ticket about my problem: https://code.djangoproject.com/ticket/8384 It suggests sorting with Python as workaround. I found it quite unsatisfying. Firstly if I sort with a Python method (like below) instead of ordering at model level I cannot use generic views. Secondly ordering with a Python method returns the very same result as the SQLite order_by does: ’Čapek’ and ’Örkény’ are placed after section 'z'.
author_list = sorted(Author.objects.all(), key=lambda x: (x.lastname, x.firstname))
How could I get the queryset ordered correctly?
Thanks to the link CL wrote in his comment, I managed to overcome the difficulties that I replied about. I answer my question to share the piece of code that worked because using Pyuca to sort querysets seems to be a rare and undocumented case.
# import section
from pyuca import Collator
# Calling Collator() takes some seconds so you should create it as reusable variable.
c = Collator()
# ...
# main part:
author_list = sorted(Author.objects.all(), key=lambda x: (c.sort_key(x.lastname), c.sort_key(x.firstname)))
The point is to use sort_key method with the attribute you want to sort by as argument. You can sort by multiple attributes as you see in the example.
Last words: In my language (Hungarian) we use four different accented version of the Latin letter ‘o’: ‘o’, ’ó’, ’ö’, ’ő’. ‘o’ and ‘ó’ are equal in sorting, and ‘ö’ and ‘ő’ are equal too, and ‘ö’/’ő’ are after ‘o’/’ó’. In the default collation table the four letters are equal. Now I try to find a way to define or find a localized collation table.
You could create a new field in the table, fill it with the result of unidecode, then sort according to it.
Using a property to provide get/set methods could help in keeping the fields in sync.
So I have the following code, and it works:
for count in range(0,1000):
L=[random.randint(0, 127),random.randint(0, 127),random.randint(0, 127)]
random.randint(0, 127)
name=''.join(map(chr,L))
number=random.randint(0,1000)
x.execute('insert into testTable set name=(%s), number=(%s)', (name, number))
Above, x is just the cursor I made (obviously). I just create a random string from ASCII values and a random number and write it to my database (this was a purely BS example so that I knew it worked)/
Then,
I have in another script:
x.execute('insert into rooms set \
room_name=(%s),\
room_sqft=(%s),\
room_type=(%s),\
room_purpose=(%s) ,\
room_floor_number=(%s)',
(name, sqft, roomType, room_use_ranking, floor))
And I get a syntax error: invalid syntax on the first line, right at the x. part of x.execute.
What is different between the two lines? In the problem code, all arguments but name are ints (name is a string) that are gotten from a int(raw_input(...)) type prompt that catches bad input errors.
Clearly this works, but what is going wrong in the second piece of code?
Thanks,
nkk
There's a problem on the line BEFORE the x.execute. (x is unexpected at this point). Can you link more of the file?
Also, try this formatting, which can clear up this sort of thing by making the string one blob. (Your syntax highlighter should show it as one big multi-line string, too!)
sql = '''
INSERT INTO rooms
SET room_name=(%s),
room_sqft=(%s),
room_type=(%s),
room_purpose=(%s),
room_floor_number=(%s)
'''
x.execute(sql, (name, sqft, roomType, room_use_ranking, floor))