The code i have is:
for key in keys:
cursor.execute("""
ALTER TABLE segment_table ADD %s VARCHAR(40)
""", key)
I get a error telling me my syntax is wrong. When I replace the %s with a actual string the syntax error goes away.
for key in keys:
cursor.execute("""
ALTER TABLE segment_table ADD myColumn VARCHAR(40)
""")
Any help is appreciated.
There is a bit of confusion going here, for several reasons:
(1) mySQL uses the % as a parameter marker -- easily confused with the % in Python's string % (data1, data2, etc)
(2) some people seem not to be aware that parameter markers can be used only where an expression can be used in SQL syntax -- this excludes table names, column names, function names, keywords, etc
(3) code-golf onelinerism
Required SQL: ALTER TABLE segment_table ADD myColumn VARCHAR(40)
Using a parameter doesn't work:
key = "myColumn"
sql = "ALTER TABLE segment_table ADD %s VARCHAR(40)" # col name not OK as parm
cursor.execute(sql, (key, ))
You need to build an acceptable SQL statement, using e.g. Python string formatting:
key = "myColumn"
sql = "ALTER TABLE segment_table ADD %s VARCHAR(40)" % key
cursor.execute(sql)
Shouldn't you do the replacement before feeding it?
query = "ALTER TABLE segment_table ADD %s VARCHAR(40)" % (key)
cursor.execute( query )
when cursor.execute() replace %s in a query string it adds ' ' to the argument values supplied...so when you do
key = 'abc'
cursor.execute("""
ALTER TABLE segment_table ADD %s VARCHAR(40)
""", key)
the query executed is
ALTER TABLE segment_table ADD 'abc' VARCHAR(40)
to which mysql will throw a syntax error coz the column names, table names can be in `` but not ' '
so this will work
query = "ALTER TABLE segment_table ADD %s VARCHAR(40)" % (key)
Related
I'm using python's psycopg2 to create a table and the insert SQL string look like this
create_table ='''CREATE TABLE Datetime_Response(
rid BIGINT NOT NULL,
qid BIGINT,
roid BIGINT,
rotext VARCHAR(20)
)'''
INSERT INTO Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
But the output is weird. All the datetime string becomes 0. I tried both VARCHAR and TEST in the column rotext. They all show 0. I don't know what goes wrong.
(13020638659, 711799502, 4681912759, '0')
This is what the values looks like
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
And this is what the insert syntax look like
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES
(13020638659, 711799502, 4681912759, 07/21/2021)
Do it like this. Let the connector fill in the properly quoted values:
sql_string = "INSERT INTO %s (%s)\nVALUES (%s)" % (
table_name,
','.join(columns),
','.join(['?']*len(values))
)
cur.execute( sql_string, values )
Because 7 divided by 21 divided by 2021 is close to zero. / is integer division in Python 2 if both operands are an integer. Quote your value: 07/21/2021
Your query is open to SQL injection attacks by malicious users of your script!
values = list(entry.values())
print(values)
['13020638659', '711799502', '4681912759', '07/21/2021']
values_str = "(%s)" % (', '.join( values ))
sql_string = "INSERT INTO %s (%s)\nVALUES\n %s" % (
table_name,
', '.join(columns),
values_str
)
print(sql_string)
When using your string values to format your string, you will end up with:
INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext)
VALUES (13020638659, 711799502, 4681912759, 07/21/2021)
which does not contain any quotation marks. Use prepared statements to avoid problems caused by wrong types and to stop hackers from misusing your application/database.
If, for whatever reason, you cannot use prepared statements, make sure the string ends up as string in your final statement:
values = ['13020638659', '711799502', '4681912759', "'07/21/2021'"]
or INSERT INTO GZ_Datetime_Response (rid, qid, roid, rotext) VALUES (%s, %s, %s, '%s)
I have a python script that executes some simple SQL.
c.execute("CREATE TABLE IF NOT EXISTS simpletable (id integer PRIMARY KEY, post_body text, post_id text, comment_id text, url text);")
command = "INSERT OR IGNORE INTO simpletable VALUES ('%s', '%s', '%s', '%s')" % (comments[-1].post_body, comments[-1].post_id, comments[-1].comment_id,
comments[-1].url)
c.execute(command)
c.commit()
But when I execute it, I get an error
sqlite3.OperationalError: table simpletable has 5 columns but 4 values were supplied
Why is it not automatically filling in the id key?
In Python 3.6 I did as shown below and data was inserted successfully.
I used None for autoincrementing ID since Null was not found.
conn.execute("INSERT INTO CAMPAIGNS VALUES (?, ?, ?, ?)", (None, campaign_name, campaign_username, campaign_password))
The ID structure is as follows.
ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
If you don't specify the target columns VALUES is expected to provide values for all columns and that you didn't do.
INSERT
OR IGNORE INTO simpletable
(text,
post_id,
comment_id,
text)
VALUES ('%s',
'%s',
'%s',
'%s');
Specifying the target columns is advisable in any case. The query won't break, if, for any reason, the order of the columns in the tables changes.
try to specify the columns names to ensure that the destination of values doesn't depends on order.
ex:
INTO simpletable
(text,
post_id,
comment_id,
text)
And if you wants the id column to be automatically incremented make sure to add Identity property on, or similar auto increment of your dbms.
ex:
CREATE TABLE IF NOT EXISTS simpletable (id integer PRIMARY KEY Identity(1,1),
and remember your script is not prepared to alter the table structure, only creation.
If you wrote code correctly delete your SQL file(name.db) and run your code again some time it solve the problem.
Imagine this is your code:
cursor.execute('''CREATE TABLE IF NOT EXISTS food(name TEXT , price TEXT)''')
cursor.execute('INSERT INTO food VALUES ("burger" , "20")')
connection.commit()
and you see an error like this:
table has 1 column but 2 values were supplied
it happened because for example you create a file with one column and then you modify your file to two column but you don't change the file name so compiler do not over write it because it exist.
Hi I'm doing something like:
# pyodbc extension
cursor.execute("select a from tbl where b=? and c=?", x, y)
-- some values in the query in provided by variables. But sometimes the variable is interpreted as #P1 in the query.
For example:
import pyodbc
ch = pyodbc.connect('DRIVER={SQL Server};SERVER=xxxx;DATABASE=xxx;Trusted_Connection=True')
cur = ch.cursor()
x = 123
cur.execute('''
CREATE TABLE table_? (
id int IDENTITY(1,1) PRIMARY KEY,
obj varchar(max) NOT NULL
)
''', x).commit()
This results in a new table named table_#P1 (I want table_123)
Another example:
x = 123
cur.execute('''
CREATE TABLE table_2 (
id int IDENTITY(1,1) PRIMARY KEY,
obj varchar(?) NOT NULL
)
''', x).commit()
it reports error:
ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server
Driver][SQL Server]Incorrect syntax near '#P1'. (102)
(SQLExecDirectW)")
Again, the variable is interpreted as #P1.
Anyone know how to fix this? Any help's appreciated. Thanks-
In your first case, parameter substitution does not work for table/column names. This is common to the vast majority of (if not all) database platforms.
In your second case, SQL Server does not appear to support parameter substitution for DDL statements. The SQL Server ODBC driver converts the pyodbc parameter placeholders (?) to T-SQL parameter placeholders (#P1, #P2, ...) so the statement passed to SQL Server is
CREATE TABLE table_2 (id int IDENTITY(1,1) PRIMARY KEY, obj varchar(#P1) NOT NULL
specifically
exec sp_prepexec #p1 output,N'#P1 int',N'CREATE TABLE table_2 (id int IDENTITY(1,1) PRIMARY KEY, obj varchar(#P1) NOT NULL',123
and when SQL Server tries to prepare that statement it expects a literal value, not a parameter placeholder.
So, in both cases you will need to use dynamic SQL (string formatting) to insert the appropriate values.
There is a way to do this sort of thing. What you need to do is dynamically build the command (ideally as a nvarchar( MAX), not varchar( MAX)) string variable and pass that variable to the cur.execute() - or any other - command. Modifying your first example accordingly:
ch = pyodbc.connect( 'DRIVER={SQL Server};SERVER=xxxx;DATABASE=xxx;Trusted_Connection=True' )
cur = ch.cursor()
x = 123
SQL_Commands = 'CREATE TABLE table_' + str( x ) + '''
(
id int IDENTITY(1,1) PRIMARY KEY,
obj varchar(max) NOT NULL
) '
'''
cur.execute( SQL_Commands ).commit()
BTW, you shouldn't try to do everything in one line, if only to avoid problems like this one. I'd also suggest looking into adding "autocommit=True" to your connect string, that way you wouldn't have to append .commit() to cur.execute().
I'm practicing in SQLite and Python. I'm trying to build a TABLE using only user prompts as database objects. After some extensive searches (official documentation says nothing about this kind of syntax-please correct me!) I found this method:
new_table = raw_input('Enter a table name: ')
column = raw_input('Enter column name: ')
cur.execute(''' CREATE TABLE IF NOT EXISTS {tn} ({col})'''\
.format(tn = new_table, col = column))
It works very nice and I find it intuitive. My problem is with INSERT INTO syntax. While the following code works ok:
cur.execute("INSERT INTO {tn} ({col}) VALUES (?)", ('goodmorning')\
.format(tn=new_table, col=column))
This code below, won't work:
insdata = raw_input('Insert data for column: ')
cur.execute("INSERT INTO {tn} ({col}) VALUES (?)", (insdata,)\
.format(tn=new_table, col=column))
and fails with error: 'tuple' object has no attribute format.
Question is: what is the proper syntax to assign insdata value to SQLite VALUES?
If you write this is a slightly clearer fashion, you'll see what's going on:
cur.execute(
"INSERT INTO {tn} ({col}) VALUES (?)",
(insdata,).format(tn=new_table, col=column)
)
You're not formatting the string, you're formatting the a tuple of arguments. Instead, you want:
cur.execute(
"INSERT INTO {tn} ({col}) VALUES (?)".format(tn=new_table, col=column),
(insdata,)
)
or perhaps a little more clearly :
sql = "INSERT INTO {tn} ({col}) VALUES (?)".format(tn=new_table, col=column)
cur.execute(sql, (insdata,))
In this case your line continuation character is not needed at all (since you're inside a function call) but if it were needed it would make much more sense to position it between arguments rather than between an object and the method invocation on the object.
I think you are invoking format method of tuple (which appears not to have one) instead of a string with SQL query:
cur.execute("INSERT INTO {tn} ({col}) VALUES ({val})".format(tn=new_table,col=column,val='goodmorning'))
I am getting this error when I run my program in Python.
Here's the table of my database :
Field Type Collation Null Key Default
articleCode varchar(25) latin1_swedish_ci NO UNI
dateReceived datetime NULL NO MUL 0000-00-00 00:00:00
s100RSD datetime NULL YES 0000-00-00 00:00:00
remarks longtext latin1_swedish_ci YES
And to simplify the problem of my program, I will isolate the part of the program that makes an error, here:
import MySQLdb
def main():
dateReceived = '2011-10-07 01:06:30'
articleCode = 'name'
s100rsd = '2011-10-07 01:06:30'
remark_text = 'This is a remark'
db = MySQLdb.connect('server', 'user', 'passwd', 'table_name', port)
cur = db.cursor()
db_query = cur.execute("INSERT INTO tblS100CurrentListing (articleCode, dateReceived, s100RSD, remarks) VALUES ('articleCode', 'dateReceived', 's100rsd', 'remark_text')")
cur.close()
db.close()
if __name__ == '__main__':
main()
Here's the error that I get : _mysql_exceptions.IntegrityError: (1062, "Duplicate entry '2147483647' for key 1")
Thanks for all your help!
You seem to be inserting constants into the database, not your actual values. Instead, try something similar to;
db_query = cur.execute("INSERT INTO tblS100CurrentListing " +
"(articleCode, dateReceived, s100RSD, remarks) VALUES (%s, %s, %s, %s)",
(articleCode, dateReceived, s100rsd, remark_text))
This happens because the limit of Key. If it is INTEGER, 2147483647 is the limit. You can choose something like BIGINT or the one bigger than INTEGER. All records after 2147483647 will be tried to write on value 2147483647. So this is why you are having this problem. Change it with BIGINT / LARGEINT or something like this.
Hope it helps.
Unique key on field "articleCode" preventing MySQL to have two records in this column with the same content. Seems like you already inserted one on the first program run.
Remove previously inserted record with articleCode = 'name' OR remove UNIQUE KEY on articleCode field OR try to insert different value of articleCode.
Hope this helps!
After correcting the code as described in other answers, you should modify the table in order to reset its auto_increment counter.
ALTER TABLE tblS100CurrentListing auto_increment=1
should reset the counter to the lowest possible value.
Removing or repairing the erroneous values from the table is required; otherwise the change won't have any effect.
Besides, is it really needed to insert a field which is set to auto_increment? Or is this part of a restore process? Otherwise, the two things are redundant: either you get the data automatically or you insert them. Both can (as seen) lead to conflicts.