This question already has answers here:
Is there an SQLite equivalent to MySQL's DESCRIBE [table]?
(7 answers)
Closed 7 years ago.
How can I see the structure of table in SQLite as desc was in Oracle?
PRAGMA table_info(table_name);
This will work for both: command-line and when executed against a connected database.
A link for more details and example. thanks
SQLite Pragma Command
Invoke the sqlite3 utility on the database file, and use its special dot commands:
.tables will list tables
.schema [tablename] will show the CREATE statement(s) for a table or tables
There are many other useful builtin dot commands -- see the documentation at http://www.sqlite.org/sqlite.html, section Special commands to sqlite3.
Example:
sqlite> entropy:~/Library/Mail>sqlite3 Envelope\ Index
SQLite version 3.6.12
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
addresses ews_folders subjects
alarms feeds threads
associations mailboxes todo_notes
attachments messages todos
calendars properties todos_deleted_log
events recipients todos_server_snapshot
sqlite> .schema alarms
CREATE TABLE alarms (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, alarm_id,
todo INTEGER, flags INTEGER, offset_days INTEGER,
reminder_date INTEGER, time INTEGER, argument,
unrecognized_data BLOB);
CREATE INDEX alarm_id_index ON alarms(alarm_id);
CREATE INDEX alarm_todo_index ON alarms(todo);
Note also that SQLite saves the schema and all information about tables in the database itself, in a magic table named sqlite_master, and it's also possible to execute normal SQL queries against that table. For example, the documentation link above shows how to derive the behavior of the .schema and .tables commands, using normal SQL commands (see section: Querying the database schema).
You can query sqlite_master
SELECT sql FROM sqlite_master WHERE name='foo';
which will return a create table SQL statement, for example:
$ sqlite3 mydb.sqlite
sqlite> create table foo (id int primary key, name varchar(10));
sqlite> select sql from sqlite_master where name='foo';
CREATE TABLE foo (id int primary key, name varchar(10))
sqlite> .schema foo
CREATE TABLE foo (id int primary key, name varchar(10));
sqlite> pragma table_info(foo)
0|id|int|0||1
1|name|varchar(10)|0||0
You should be able to see the schema by running
.schema <table>
.schema TableName
Where TableName is the name of the Table
You will get the structure by typing the command:
.schema <tableName>
If you are using PHP you can get it this way:
<?php
$dbname = 'base.db';
$db = new SQLite3($dbname);
$sturturequery = $db->query("SELECT sql FROM sqlite_master WHERE name='foo'");
$table = $sturturequery->fetchArray();
echo '<pre>' . $table['sql'] . '</pre>';
$db->close();
?>
You can use the Firefox add-on called SQLite Manager to view the database's structure clearly.
Related
I have the following table stored as a csv file:
project_number,project_name
1,project_1
2,project_2
3,project_3
I figured out how to import this and show its schema in an sqlite3 database as follows:
sqlite> .mode csv
sqlite> .import
sqlite> .import test.csv test
sqlite> .schema test
CREATE TABLE test(
"project_number" TEXT,
"project_name" TEXT
);
I would like to now set the column project_number as my primary key and also set it to be an integer. I understand from previous questions that this is difficult to do by altering the original table, so I tried to create a new table an populated using a combination of create table, create table as, insert into and select * from as indicated here
sqlite> create table test_2 (project_name text, project_number primary key);
sqlite> insert into test_2 (select project_name, project_number from test);
Error: near "select": syntax error
But as you can see this caused a syntax error and I don't understand why. How do I set the primary key for tables imported from csvs?
You can also create the table first and then import data into it. Assuming a Linux or Unix environment:
sqlite> create table test(project_number integer primary key, project_name text);
sqlite> .mode csv
sqlite> .import '| tail -n +2 test.csv' test
will skip the first header row in the file and insert the rest.
Try this:
insert into test_2 (project_number, project_name)
select project_number, project_name from test;
I guess insert into example at https://dba.stackexchange.com/a/41108/26454 is wrong: one need to list columns after table name, reference.
So I made a table using this command
.open C:/Users/Fries/Desktop/Test.db
I closed SQL lite and populated the db with the data below using notepad
CREATE TABLE Persons (
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);
When I open the db and type .tables there is an error for some reason
The commands do work when used properly.
In short what you have done, is
Create and save a database that has no tables.
Open that file with Notepad (despite warnings that you may have received)
Entered some data and saved the file.
Thus deleting eveything in the file that SQLite knows about so when you open it SQLite tells you that it's not a database e.g. the first 16 bytes must be SQLite format 3\000 (see below when the database file is opened in notepad).
Open the file from within the SQLITE3 program which has then told you it's not a database.
i.e. The file that you open is the actual database not something that you have typed into notepad.
The data, which will be in columns of a table or tables. Has to be entered via SQLITE3 commands (including SQL). The CREATE TABLE... is one such SQL command (yours is valid and has been used below as it is).
What you should be doing is starting SQLIT3 (typing sqlite3 if it's path has been added to the PATH environment variable), and then entering commands such as CREATE TABLE ......
E.G.
When you first start sqlite3 from a command prompt you will get :-
C:\Users\Mike>sqlite3
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
A database is opened as such but it is an in memory database and would be lost if you quit.
You can create an on disk database by opening it (even if it doesn't exist) using .open and then entering commands. Alternately you can enter commands and then then use the .save command afterwards to save the in-memory database to disk.
So after the above you could do :-
sqlite> .open Test.db
sqlite> CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) );
sqlite> SELECT * FROM Sqlite_master;
table|Persons|Persons|3|CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) )
sqlite> .quit
This creates the file Test.db (which didn't exists, otherwise it would open it)
Then creates the Persons table.
And then extracts the rows in the system table named sqlite_master (lists items including tables).
Finally it quites from SQLITE3.
Perhaps you could then do
:-
C:\Users\Mike>sqlite3 SQLite version 3.22.0 2018-01-22 18:45:57 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open Test.db
sqlite> .tables Persons
sqlite> INSERT INTO Persons VALUES (1,'Smith','Fred','Somewhere','London');
sqlite> select * FROM persons; 1|Smith|Fred|Somewhere|London sqlite> .quit
Starts SQLITE3
Opens the now existing Test.db file.
Lists the tables.
inserts a row
dispslays the rows in the Persons table (i.e. the row just added)
Finally quits SQLITE3
Opening the file Test.db in notepad :-
SQLite format 3 # .°
e e ‚tablePersonsPersonsCREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255) )
You may see some familiar data (e.g. the SQL used to create the table is stored in the sqlite_master table in the column named SQL and will be visible as is)
Other data will not be shown in a usefule/usable format.
i.e. You will find it between hard and impossible to enter the correct data to create a valid SQLite3 database file in notepad.
Is it possible to add an ON DELETE CASCADE to a table after it has been created?
My schema is as follows:
CREATE TABLE skills(name varchar, skill varchar, level int, foreign key(name) references runners(name), primary key(name, skill));
And I would like to cascade if the foreign key is deleted.
SQLite's ALTER TABLE command cannot do what you want.
However, it is possible to bypass the SQL interpreter and change the internal table definition directly.
SQLite stores table definitions as a textual copy of the CREATE TABLE command in its sqlite_master table; check out the result of this query:
SELECT sql FROM sqlite_master WHERE type='table' AND name='skills';
Add your cascade specification to that string, then enable write access to sqlite_master with PRAGMA writable_schema=1; and write your new table definition into it:
UPDATE sqlite_master SET sql='...' WHERE type='table' AND name='skills';
Then reopen the database.
WARNING: This works only for changes that do not change the on-disk format of the table. If you do make any change that changes the record format (such as adding/removing fields, or modifying the rowid), your database will blow up horribly.
My application logs user access to sqlite database, the my.db file grows about 5Gb every month. There're tables like "access" which logs every user access, this table should be cleared at every beginning of the month, and it holds almost all the 5gb data. Another table "user" which holds all my users, this table should always keep its data.
So every month I need to:
ctrl+c -> ctrl+v my.db to clone a file copy(for future statistics), this is very slow for 5gb file.
clear the "access" table via "delete from access" and "vacuum", it also takes some time.
It's too slow. I wonder if there is a sql command like "export/import database structure and indices" to clone only the structure to another new.db, and then "copy * from mydb.user to newdb"
Or maybe some existing tool can do this?
Here's the sample database I'll use, representing your old database. I made a table to keep, a table to lose, and an index.
$ sqlite3 old.db
sqlite> create table KeepMe (a TEXT);
sqlite> create table DeleteMe (b TEXT);
sqlite> create index DeleteMe_b on DeleteMe(b);
sqlite> insert into KeepMe values("Hello");
sqlite> insert into DeleteMe values("World");
sqlite> .quit
First copy the schema to a new database:
$ sqlite3 old.db .schema | sqlite3 new.db
Then open the new database, ATTACH to the old database, and copy over the table(s) you want:
$ sqlite3 new.db
sqlite> attach "old.db" as old;
sqlite> insert into KeepMe select * from old.KeepMe;
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE KeepMe (a TEXT);
INSERT INTO "KeepMe" VALUES('Hello');
CREATE TABLE DeleteMe (b TEXT);
CREATE INDEX DeleteMe_b on DeleteMe(b);
COMMIT;
sqlite> .quit
How do I alter column in sqlite?
This is in Postgresql
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;
I believe there is no ALTER COLUMN in sqlite at all, only ALTER TABLE is supported.
Any idea? Thanks!
There's no ALTER COLUMN in sqlite.
I believe your only option is to:
Rename the table to a temporary name
Create a new table without the NOT NULL constraint
Copy the content of the old table to the new one
Remove the old table
This other Stackoverflow answer explains the process in details
While it is true that the is no ALTER COLUMN, if you only want to rename the column, drop the NOT NULL constraint, or change the data type, you can use the following set of dangerous commands:
PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;
You will need to either close and reopen your connection or vacuum the database to reload the changes into the schema.
For example:
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT
NULL);**
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
Error: BOOKS.publication_date may not be NULL
sqlite> **PRAGMA writable_schema = 1;**
sqlite> **UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT
NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';**
sqlite> **PRAGMA writable_schema = 0;**
sqlite> **.q**
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
sqlite> **.q**
REFERENCES FOLLOW:
pragma writable_schema
When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file.
[alter table](From http://www.sqlite.org/lang_altertable.html)
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table. But you can alter table column datatype or other property by the following steps.
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT
For more detail you can refer the link.
CREATE TABLE temp_Table(x,y[,etc]);
INSERT INTO temp_Table SELECT * FROM Table;
DROP TABLE Table;
ALTER TABLE temp_Table RENAME TO Table;
Thanks for helping me to find a definitive method!
ALTER COLUMN does not exist in SQLite.
Only Supported alter operations:
Alter Table Name
Alter Table Column Name
Add New Column
Drop Column
Alex Jasmin's answer shows possible way
Reference:
Sqlite Alter Table