Unconsumed column names sqlalchemy python - python

I am facing the following error using SQLAlchemy: Unconsumed column names: company
I want to insert data for 1 specific column, and not all columns in the table: INSERT INTO customers (company) VALUES ('sample name');
My code:
engine.execute(table('customers').insert().values({'company': 'sample name'}))
Create Table:
'CREATE TABLE `customers` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`company` varchar(255) DEFAULT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
`phone` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`),
UNIQUE KEY `company_UNIQUE` (`company`)
) ENGINE=InnoDB AUTO_INCREMENT=63 DEFAULT CHARSET=utf8'

After hours of frustration, I was able to test a way that I think works for my use case. As we know, you can insert to specific columns, or all columns in a table. In my use case, I dynamically need to insert to the customers table, depending on what columns a user has permissions to insert to.
I found that I needed to define all columns in the table() method of sqlalchemy, but I can pass in whatever columns and values that I need dynamically to the values() method.
Final code:
engine.execute(table('customers', column('company'), column('first_name'), column('last_name'), column('email'), column('phone')).insert().values({'company': 'sample name'}))

The original solution works great, however I'd like to add another approach that will allow working with tables dynamically, without specifying all of their columns. This can be useful when working with multiple tables.
We can use the Table class from sqlalchemy.schema and provide our engine to its autoload_with parameter, which will reflect the schema and populate the columns for us.
Then, we can work just like we in the OP's answer.
from sqlalchemy.schema import Table, MetaData
my_table_name = 'customers' # Could be passed as an argument as well :)
table = Table(my_table_name, MetaData(), autoload_with=engine)
engine.execute(my_table.insert({'company': 'sample name'}))

Related

SQLite AUTO_INCREMENT id field not working

I am trying to create a database using python to execute the SQL commands (for CS50x problem set 7).
I have created a table with an id field set to AUTO_INCREMENT, but the field in the database is populated only by NULL values. I just want it to have an incrementing id starting at 1.
I've tried searching online to see if I'm using the right syntax and can't find anything obvious, nor can I find someone else with a similar problem, so any help would be much appreciated.
Here is the SQL command I am running:
# For creating the table
db.execute("""
CREATE TABLE students (
id INTEGER AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
middle_name VARCHAR(255) DEFAULT (NULL),
last_name VARCHAR(255) NOT NULL,
house VARCHAR(10),
birth INTEGER
);
""")
# An example insert statement
db.execute("""
INSERT INTO students (
first_name,
middle_name,
last_name,
house,
birth
)
VALUES (
?, ?, ?, ?, ?
);
""", "Harry", "James", "Potter", "Gryffindor", 1980)
Here is a screenshot of the database schema shown in phpliteadmin :
And here is a screenshot of the resulting database:
My guess is that you are using SQLite with phpliteadmin and not MySql, in which case this:
id INTEGER AUTO_INCREMENT PRIMARY KEY
is not the correct definition of the auto increment primary key.
In fact, the data type of this column is set to INTEGER AUTO_INCREMENT, as you can see in phpliteadmin, which according to 3.1. Determination Of Column Affinity, has INTEGER affinity.
Nevertheless it is the PRIMARY KEY of the table but this allows NULL values.
The correct syntax to have an integer primary key is this:
id INTEGER PRIMARY KEY AUTOINCREMENT
This cannot happen, if your statements are executed correctly.
I notice that you are not checking for errors in your code. You should be doing that!
My guess is that the table is already created without the auto_increment attribute. The create table is generating an error and you are inserting into the older version.
You can fix this by dropping the table before you create it. You should also modify the code to check for errors.

how to block the possibility of adding the same values ​to the database python?

how to block the possibility of adding the same values ​​to the database, for example e-mail addresses in python and MySQL?
From database perspective, you would typically put a unique constraint on the corresponding table column:
create table users (
id int auto_increment primary key,
name varchar(50) not null,
email varchar(100) not null unique
);
With this set up in place, any query that would attempt generating a duplicate email (either from an INSERT or an UPDATE) would fail with a unique contraint violation error.

MySQL would not create a table if I change the name of a column

I am using a python code to create MySQL tables.
I am fine to create table using a specific name for my columns, but as soon as I want to change them, the tables are not created anymore.
This code bellow works without any problems
DROP TABLE IF EXISTS sector_tb;
CREATE TABLE sector_tb (
id INT NOT NULL AUTO_INCREMENT,
sector VARCHAR(255) NOT NULL DEFAULT '',
district_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX sector (sector)
)
COLLATE='latin1_swedish_ci'
;
As soon as I decide to change the name of 'sector' to 'sector1' or anything else, MySQL does not create the table anymore. The code below does not create the table anymore.
CREATE TABLE sector_tb (
id INT NOT NULL AUTO_INCREMENT,
sector1 VARCHAR(255) NOT NULL DEFAULT '',
district_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX sector (sector)
)
COLLATE='latin1_swedish_ci'
;
There are no errors shown while running the code.
There is an obvious error in second statement:
column name in the index doesn't match column name in the table.
sector1 VARCHAR(255)
UNIQUE INDEX sector (sector)
If your Python code does not report any errors, you must improve error handling.
Two options - drop the original sector_tb and run your second script or rename your column using the alter table command.

How to use auto increase primary key using PyGreSQL and PostgreSQL

I have a table in my PostgreSQL:
CREATE SEQUENCE dember_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE TABLE dember (id INT NOT NULL, did VARCHAR(255) DEFAULT NULL, dnix VARCHAR(255) DEFAULT NULL, durl TEXT DEFAULT NULL, created TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, modified TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, status BOOLEAN NOT NULL, dnickname VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id));
When I want to insert a record, I using the following code:
import pg
db = pg.DB(....)
db.insert('dember',{'did':did,'dnix':dnix,'durl',durl,'created',now, 'modified':now, 'status':'true','dnickname':nickname'})
Then the insert code does not work, I get the following error:
pg.ProgrammingError: ERROR: null value in column "id" violates not-null constraint
It looks that I have to add {'id':number} to the value dictionary.
Any suggestions? Thanks.
You should save yourself some trouble and use serial instead of int:
The data types serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases).
So saying:
create table t (
id serial not null primary key
-- ...
)
will create id as an integer column, create a sequence for it, set the default value of id to be the next value in the sequence, and set the sequence's owner to the id column; the last bit is important, the implied
ALTER SEQUENCE t_id_seq OWNED BY t.id;
that a serial type does ensures that the sequence will be dropped when the column goes away. If you don't set the sequence's owner, you can be left with dangling unused sequences in your database.
You forgot to assign the sequence to the column.
CREATE TABLE dember (id INT NOT NULL DEFAULT nextval('dember_id_seq'), ...

A table with a composite Primary key, one of the fields with autoincrement

Im using a table constraint to create a composite primary key, I would like the id field to autoincrement, is this possible? or what are the alternatives?
CREATE TABLE IF NOT EXISTS atable(
id INTEGER NOT NULL, --I want to autoincrement this one
name TEXT NOT NULL,
anotherCol TEXT,
PRIMARY KEY(id, name));
No, there's only one primary key: that's the composite of id and name.
If you mean that you want id to be the primary key, and name to be an indexed alternate key, I'd say that you should give name a unique constraint and make id the primary key.
Here's the link to the SQLite FAQ page where your question of how to autoincrement an integer primary key is #1. http://www.sqlite.org/faq.html#q1
Here's your SQL reworked a little:
CREATE TABLE IF NOT EXISTS atable(
id INTEGER PRIMARY KEY, -- use NULL for this column on INSERT to autoinc
name TEXT NOT NULL,
anotherCol TEXT);
then create a unique index on NAME as suggested by duffymo and Kaleb.
It doesn't look to me that the OP want names to be unique. (But I could be wrong.) At any rate, you can
get an autoincrementing integer by using INTEGER PRIMARY KEY and inserting NULL into that column, and
declare a superkey by using a UNIQUE constraint on (id, name).
A superkey is just a candidate key (primary key in this case) plus one or more columns.
CREATE TABLE yourtable(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
CONSTRAINT superkey UNIQUE (id, name)
);
If you turn on foreign key support using PRAGMA foreign_keys = on;, the superkey can be the target of foreign key constraints in other tables. But I'm not certain that's what you were looking for.

Categories

Resources