Can we do autoincrement string in sqlite3? IF not how can we do that?
Exemple:
RY001
RY002
...
With Python, I can do it easily with print("RY"+str(rowid+1)). But how about it performances?
Thank you
If your version of SQLite is 3.31.0+ you can have a generated column, stored or virtual:
CREATE TABLE tablename(
id INTEGER PRIMARY KEY AUTOINCREMENT,
str_id TEXT GENERATED ALWAYS AS (printf('RY%03d', id)),
<other columns>
);
The column id is declared as the primary key of the table and AUTOINCREMENT makes sure that no missing id value (because of deletions) will ever be reused.
The column str_id will be generated after each new row is inserted, as the concatenation of the 'RY' and the left padded with 0s value of id.
As it is, str_id will be VIRTUAL, meaning that it will be created every time you query the table.
If you add STORED to its definition:
str_id TEXT GENERATED ALWAYS AS (printf('RY%03d', id)) STORED
it will be stored in the table.
Something like this:
select
printf("RY%03d", rowid) as "id"
, *
from myTable
?
Related
I create a table with primary key and autoincrement.
with open('RAND.xml', "rb") as f, sqlite3.connect("race.db") as connection:
c = connection.cursor()
c.execute(
"""CREATE TABLE IF NOT EXISTS race(RaceID INTEGER PRIMARY KEY AUTOINCREMENT,R_Number INT, R_KEY INT,\
R_NAME TEXT, R_AGE INT, R_DIST TEXT, R_CLASS, M_ID INT)""")
I want to then insert a tuple which of course has 1 less number than the total columns because the first is autoincrement.
sql_data = tuple(b)
c.executemany('insert into race values(?,?,?,?,?,?,?)', b)
How do I stop this error.
sqlite3.OperationalError: table race has 8 columns but 7 values were supplied
It's extremely bad practice to assume a specific ordering on the columns. Some DBA might come along and modify the table, breaking your SQL statements. Secondly, an autoincrement value will only be used if you don't specify a value for the field in your INSERT statement - if you give a value, that value will be stored in the new row.
If you amend the code to read
c.executemany('''insert into
race(R_number, R_KEY, R_NAME, R_AGE, R_DIST, R_CLASS, M_ID)
values(?,?,?,?,?,?,?)''',
sql_data)
you should find that everything works as expected.
From the SQLite documentation:
If the column-name list after table-name is omitted then the number of values inserted into each row must be the same as the number of columns in the table.
RaceID is a column in the table, so it is expected to be present when you're doing an INSERT without explicitly naming the columns. You can get the desired behavior (assign RaceID the next autoincrement value) by passing an SQLite NULL value in that column, which in Python is None:
sql_data = tuple((None,) + a for a in b)
c.executemany('insert into race values(?,?,?,?,?,?,?,?)', sql_data)
The above assumes b is a sequence of sequences of parameters for your executemany statement and attempts to prepend None to each sub-sequence. Modify as necessary for your code.
I have to create a table dynimically in sqllite with colums=['col1,'col2','col3']
so I am using:
create_query = "create table if not exists myTable1 ({0})".format(" text,".join(columns))
print(create_query)
This works.
But I have to keep "primary key" for a 3nd entry in List (or)1st entry in a List.
CREATE TABLE test (col1 primary key ,col2,col3);
Is there any condition option we can use.
Basically I dont wan just the entries but want to add primary key also.
I tried different combinations with no luck
Okay, The best way would be to add an inline for loop with an if condition to cycle through the values. To this we can add a variable column_no that will store the index of the column value to use as a primary key.
Here's what the resultant code would look like:
columns = ['col1','col2','col3']
column_no = 0
create_query = "create table if not exists myTable1 ({0})".format(' text, '.join(val+(" primary key" if i==column_no else "") for (i, val) in enumerate(columns)))
print(create_query)
I have a table in mysql with restaurants and I want to store an array for the categories the restaurants fall under. How should I do this, as mysql doesn't have an array section. So what I want is something like this:
id|name |categories |
1|chipotle|[mexican,fast_food]|
How can I do this?
Ok, give me a minute or two to add sample data and FK's
create table food
(
id int auto_increment primary key,
name varchar(100) not null
);
create table category
(
id int auto_increment primary key,
name varchar(100) not null
);
create table fc_junction
( -- Food/Category junction table
-- if a row exists here, then the food and category intersect
id int auto_increment primary key,
foodId int not null,
catId int not null,
-- the below unique key makes certain no duplicates for the combo
-- duplicates = trash
unique key uk_blahblah (foodId,catId),
-- Below are the foreign key (FK) constraints. A part of Referential Integrity (RI).
-- So a row cannot exist with faulty foodId or catId. That would mean insert/update here.
-- It also means the parents (food and category) row(s) cannot be deleted and thus
-- orphaning the children (the children are these rows in fc_junction)
CONSTRAINT fc_food FOREIGN KEY (foodId) REFERENCES food(id),
CONSTRAINT fc_cat FOREIGN KEY (catId) REFERENCES category(id)
);
So you are free to add food and categories and hook them up later via the junction table. You can create chipotle, burritos, hotdogs, lemonade, etc. And in this model (the generally accepted way = "don't do it any other way), you do not need to know what categories the foods are in until whenever you feel like it.
In the original comma-separated way (a.k.a. the wrong way), you have zero RI and you can bet there will be no use of fast indexes. Plus getting to your data, modifying, deleting a category, adding one, all of that is a kludge and there is much snarling and gnashing of teeth.
See How to store arrays in MySQL?, you need to create a separate table and use a join.
Or you can use Postgres, http://www.postgresql.org/docs/9.4/static/arrays.html.
I have a database where i store some values with a auto generated index key. I also have a n:m mapping table like this:
create table data(id int not null identity(1,1), col1 int not null, col2 varchar(256) not null);
create table otherdata(id int not null identity(1.1), value varchar(256) not null);
create table data_map(dataid int not null, otherdataid int not null);
every day the data table needs to be updated with a list of new values, where a lot of them are already present but needs to be inserted into the data_map (the key in otherdata is then generated, so in this table the data is always new).
one way of doing it would be to first try to insert all values, then select the generated id, then insert into data_map:
mydata = [] # list of tuples
cursor.executemany("if not exists (select * from data where col1 = %d and col2 = %d) insert into data (col1, col2) values (%d, %d)", mydata);
# now select the id's
# [...]
but that obviously is quite bad because i need to select all things without using the key and also i need to do the check without using the key, so i need indexed data first, otherwise everything is very slow.
my next approach was to use a hashfunction (like md5 or crc64) to generate my own hash over col1 and col2, to be able to insert all values without using a select and be able to use the indexed key when inserting missing values.
can this be optimized or is it the best thing i could do?
the amout of lines is >500k per change, where maybe ~20-50% will be already in the database.
timing wise it looks like that calculating the hashes is much faster than inserting data into the database.
As far as I concern, you use mysql.connector. If it is, when you run cursor.execute() you should not use %d types. Everything should be just %s and connector will do this job about type conversions
I have a composite PK in table Strings (integer id, varchar(2) lang)
I want to create a FK to ONLY the id half of the PK from other tables. This means I'd have potentially many rows in Strings table (translations) matching the FK. I just need to store the id, and have referential integrity maintained by the DB.
Is this possible? If so, how?
This is from wiki
The columns in the referencing table
must be the primary key or other
candidate key in the referenced table. The values in one row of the referencing columns must occur in a single row in the referenced table.
Let's say you have this:
id | var
1 | 10
1 | 11
2 | 10
The foreign key must reference exactly one row from the referenced table. This is why usually it references the primary key.
In your case you need to make another Table1(id) where you stored the ids and make the column unique/primary key. The id column in your current table is not unique - you can't use it in your situation... so you make a Table1(id - primary key) and make the id in your current table a foreign key to the Table1. Now you can create foreign keys to id in Table1 and the primary key in your current table is ok.